mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-12 19:06:09 -10:00
Soft shadows, deferred lighting, and various major graphics optimizations.
This commit is contained in:
1 parent
584ec36f62
commit
c620372357
98 files changed
+14284
-2993
No files matched your search
@@ -343,6 +343,7 @@ FS2_SOURCES = \
|
||||
graphics/grstub.cpp \
|
||||
graphics/grstub.h \
|
||||
graphics/line.h \
|
||||
graphics/shadows.cpp \
|
||||
graphics/tmapper.h \
|
||||
hud/hud.cpp \
|
||||
hud/hud.h \
|
||||
@@ -501,6 +502,7 @@ FS2_SOURCES = \
|
||||
model/modelsinc.h \
|
||||
model/modeloctant.cpp \
|
||||
model/modelread.cpp \
|
||||
model/modelrender.cpp \
|
||||
nebula/neb.cpp \
|
||||
nebula/neb.h \
|
||||
nebula/neblightning.cpp \
|
||||
|
||||
@@ -1162,7 +1162,7 @@ int asteroid_check_collision(object *pasteroid, object *other_obj, vec3d *hitpos
|
||||
}
|
||||
}
|
||||
|
||||
void asteroid_render(object * obj)
|
||||
void asteroid_render_DEPRECATED(object * obj)
|
||||
{
|
||||
if (Asteroids_enabled) {
|
||||
int num;
|
||||
@@ -1176,7 +1176,32 @@ void asteroid_render(object * obj)
|
||||
Assert( asp->flags & AF_USED );
|
||||
|
||||
model_clear_instance( Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype]);
|
||||
model_render(Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype], &obj->orient, &obj->pos, MR_NORMAL|MR_IS_ASTEROID, OBJ_INDEX(obj) ); // Replace MR_NORMAL with 0x07 for big yellow blobs
|
||||
|
||||
model_render_DEPRECATED(Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype], &obj->orient, &obj->pos, MR_DEPRECATED_NORMAL|MR_DEPRECATED_IS_ASTEROID, OBJ_INDEX(obj) ); // Replace MR_NORMAL with 0x07 for big yellow blobs
|
||||
}
|
||||
}
|
||||
|
||||
void asteroid_render(object * obj, draw_list *scene)
|
||||
{
|
||||
if (Asteroids_enabled) {
|
||||
int num;
|
||||
asteroid *asp;
|
||||
|
||||
num = obj->instance;
|
||||
|
||||
Assert((num >= 0) && (num < MAX_ASTEROIDS));
|
||||
asp = &Asteroids[num];
|
||||
|
||||
Assert( asp->flags & AF_USED );
|
||||
|
||||
model_clear_instance( Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype]);
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
render_info.set_object_number( OBJ_INDEX(obj) );
|
||||
render_info.set_flags(MR_IS_ASTEROID);
|
||||
|
||||
model_render_queue(&render_info, scene, Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype], &obj->orient, &obj->pos); // Replace MR_NORMAL with 0x07 for big yellow blobs
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
class object;
|
||||
class polymodel;
|
||||
struct collision_info_struct;
|
||||
class draw_list;
|
||||
|
||||
#define MAX_ASTEROIDS 512
|
||||
|
||||
@@ -150,7 +151,8 @@ void asteroid_init();
|
||||
void asteroid_level_init();
|
||||
void asteroid_level_close();
|
||||
void asteroid_create_all();
|
||||
void asteroid_render( object *asteroid_objp );
|
||||
void asteroid_render_DEPRECATED( object *asteroid_objp );
|
||||
void asteroid_render(object * obj, draw_list *scene);
|
||||
void asteroid_delete( object *asteroid_objp );
|
||||
void asteroid_process_pre( object *asteroid_objp, float frame_time);
|
||||
void asteroid_process_post( object *asteroid_objp, float frame_time);
|
||||
|
||||
@@ -108,6 +108,93 @@ static int Bm_ignore_load_count = 0;
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// Declaration of private functions and templates(declared as static type func(type param);)
|
||||
|
||||
bitmap_lookup::bitmap_lookup(int bitmap_num):
|
||||
Bitmap_data(NULL)
|
||||
{
|
||||
if ( !bm_is_valid(bitmap_num) ) return;
|
||||
|
||||
Num_channels = 3;
|
||||
|
||||
if ( bm_has_alpha_channel(bitmap_num) ) {
|
||||
Num_channels = 4;
|
||||
}
|
||||
|
||||
int n = bitmap_num % MAX_BITMAPS;
|
||||
|
||||
bitmap_entry *be = &bm_bitmaps[n];
|
||||
|
||||
Width = be->bm.w;
|
||||
Height = be->bm.h;
|
||||
|
||||
Bitmap_data = (float*)vm_malloc(Width * Height * Num_channels * sizeof(float));
|
||||
|
||||
gr_get_bitmap_from_texture((void*)Bitmap_data, bitmap_num);
|
||||
}
|
||||
|
||||
bitmap_lookup::~bitmap_lookup()
|
||||
{
|
||||
if ( Bitmap_data != NULL ) {
|
||||
vm_free(Bitmap_data);
|
||||
}
|
||||
}
|
||||
|
||||
bool bitmap_lookup::valid()
|
||||
{
|
||||
return Bitmap_data != NULL;
|
||||
}
|
||||
|
||||
float bitmap_lookup::map_texture_address(float address)
|
||||
{
|
||||
// assume we're just wrapping
|
||||
return address - floorf(address);
|
||||
}
|
||||
|
||||
float bitmap_lookup::get_channel_red(float u, float v)
|
||||
{
|
||||
Assert( Bitmap_data != NULL );
|
||||
|
||||
CLAMP(u, 0.0, 1.0f);
|
||||
CLAMP(v, 0.0, 1.0f);
|
||||
|
||||
int x = map_texture_address(u) * (Width-1);
|
||||
int y = map_texture_address(v) * (Height-1);
|
||||
|
||||
return Bitmap_data[(y*Width + x)*Num_channels];
|
||||
}
|
||||
|
||||
float bitmap_lookup::get_channel_green(float u, float v)
|
||||
{
|
||||
Assert( Bitmap_data != NULL );
|
||||
|
||||
CLAMP(u, 0.0, 1.0f);
|
||||
CLAMP(v, 0.0, 1.0f);
|
||||
|
||||
int x = map_texture_address(u) * (Width-1);
|
||||
int y = map_texture_address(v) * (Height-1);
|
||||
|
||||
return Bitmap_data[(y*Width + x)*Num_channels + 1];
|
||||
}
|
||||
|
||||
float bitmap_lookup::get_channel_blue(float u, float v)
|
||||
{
|
||||
Assert( Bitmap_data != NULL );
|
||||
|
||||
int x = map_texture_address(u) * (Width-1);
|
||||
int y = map_texture_address(v) * (Height-1);
|
||||
|
||||
return Bitmap_data[(y*Width + x)*Num_channels + 2];
|
||||
}
|
||||
|
||||
float bitmap_lookup::get_channel_alpha(float u, float v)
|
||||
{
|
||||
Assert( Bitmap_data != NULL );
|
||||
|
||||
int x = map_texture_address(u) * (Width-1);
|
||||
int y = map_texture_address(v) * (Height-1);
|
||||
|
||||
return Bitmap_data[(y*Width + x)*Num_channels + 3];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the bitmap referenced by bmp to the type specified by flags
|
||||
*/
|
||||
|
||||
@@ -147,6 +147,26 @@ void *bm_malloc(int handle, int size);
|
||||
*/
|
||||
void bm_update_memory_used(int n, int size);
|
||||
|
||||
class bitmap_lookup {
|
||||
float *Bitmap_data;
|
||||
|
||||
int Width;
|
||||
int Height;
|
||||
int Num_channels;
|
||||
|
||||
float map_texture_address(float address);
|
||||
public:
|
||||
bitmap_lookup(int bitmap_num);
|
||||
~bitmap_lookup();
|
||||
|
||||
bool valid();
|
||||
|
||||
float get_channel_red(float u, float v);
|
||||
float get_channel_green(float u, float v);
|
||||
float get_channel_blue(float u, float v);
|
||||
float get_channel_alpha(float u, float v);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Loads a bitmap so we can draw with it later.
|
||||
*
|
||||
|
||||
@@ -141,10 +141,11 @@ Flag exe_params[] =
|
||||
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
|
||||
{ "-post_process", "Enable post processing", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
|
||||
{ "-soft_particles", "Enable soft particles", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
|
||||
{ "-fxaa", "Enable FXAA anti-aliasing", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
|
||||
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT, EASY_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
|
||||
{ "-fxaa", "Enable FXAA anti-aliasing", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
|
||||
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
|
||||
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_explosions", },
|
||||
|
||||
{ "-no_deferred", "Disable Deferred Lighting", true, EASY_DEFAULT_MEM, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_deferred"},
|
||||
{ "-disable_shadows", "Disable Shadows", true, EASY_DEFAULT_MEM, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_shadows"},
|
||||
{ "-img2dds", "Compress non-compressed images", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-img2dds", },
|
||||
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
|
||||
{ "-no_fps_capping", "Don't limit frames-per-second", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_fps_capping", },
|
||||
@@ -196,6 +197,8 @@ Flag exe_params[] =
|
||||
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-use_gldrawelements", },
|
||||
{ "-old_collision", "Use old collision detection system", true, EASY_DEFAULT, EASY_ALL_ON, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-old_collision", },
|
||||
{ "-gl_finish", "Fix input lag on some ATI+Linux systems", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gl_finish", },
|
||||
{ "-no_batching", "Disable batched model rendering", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
{ "-no_geo_effects", "Disable geometry shader for effects", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
|
||||
|
||||
{ "-ingame_join", "Allow in-game joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
|
||||
{ "-voicer", "Enable voice recognition", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-voicer", },
|
||||
@@ -305,6 +308,10 @@ cmdline_parm fxaa_preset_arg("-fxaa_preset", "FXAA quality (0-9), requires -post
|
||||
cmdline_parm fb_explosions_arg("-fb_explosions", NULL, AT_NONE);
|
||||
cmdline_parm flightshaftsoff_arg("-nolightshafts", NULL, AT_NONE);
|
||||
cmdline_parm brieflighting_arg("-brief_lighting", NULL, AT_NONE);
|
||||
cmdline_parm no_batching("-no_batching", NULL, AT_NONE);
|
||||
cmdline_parm shadow_quality_arg("-shadow_quality", NULL, AT_NONE);
|
||||
cmdline_parm disable_shadows_arg("-disable_shadows", NULL, AT_NONE);
|
||||
cmdline_parm no_deferred_lighting_arg("-no_deferred", NULL, AT_NONE); // Cmdline_no_deferred
|
||||
|
||||
float Cmdline_clip_dist = Default_min_draw_distance;
|
||||
float Cmdline_fov = 0.75f;
|
||||
@@ -328,8 +335,11 @@ bool Cmdline_fxaa = false;
|
||||
int Cmdline_fxaa_preset = 6;
|
||||
extern int Fxaa_preset_last_frame;
|
||||
bool Cmdline_fb_explosions = 0;
|
||||
bool Cmdline_no_batching = false;
|
||||
extern bool ls_force_off;
|
||||
bool Cmdline_brief_lighting = 0;
|
||||
int Cmdline_shadow_quality = 2;
|
||||
int Cmdline_no_deferred_lighting = 0;
|
||||
|
||||
// Game Speed related
|
||||
cmdline_parm cache_bitmaps_arg("-cache_bitmaps", NULL, AT_NONE); // Cmdline_cache_bitmaps
|
||||
@@ -418,6 +428,7 @@ cmdline_parm no_drawrangeelements("-use_gldrawelements", NULL, AT_NONE); // Cmdl
|
||||
cmdline_parm keyboard_layout("-keyboard_layout", "Specify keyboard layout (qwertz or azerty)", AT_STRING);
|
||||
cmdline_parm old_collision_system("-old_collision", NULL, AT_NONE); // Cmdline_old_collision_sys
|
||||
cmdline_parm gl_finish ("-gl_finish", NULL, AT_NONE);
|
||||
cmdline_parm no_geo_sdr_effects("-no_geo_effects", NULL, AT_NONE);
|
||||
|
||||
int Cmdline_load_all_weapons = 0;
|
||||
int Cmdline_nohtl = 0;
|
||||
@@ -435,6 +446,7 @@ int Cmdline_no_di_mouse = 0;
|
||||
int Cmdline_drawelements = 0;
|
||||
char* Cmdline_keyboard_layout = NULL;
|
||||
bool Cmdline_gl_finish = false;
|
||||
bool Cmdline_no_geo_sdr_effects = false;
|
||||
|
||||
// Developer/Testing related
|
||||
cmdline_parm start_mission_arg("-start_mission", "Skip mainhall and run this mission", AT_STRING); // Cmdline_start_mission
|
||||
@@ -1534,6 +1546,11 @@ bool SetCmdlineParams()
|
||||
Cmdline_gl_finish = true;
|
||||
}
|
||||
|
||||
if ( no_geo_sdr_effects.found() )
|
||||
{
|
||||
Cmdline_no_geo_sdr_effects = true;
|
||||
}
|
||||
|
||||
if ( snd_preload_arg.found() )
|
||||
{
|
||||
Cmdline_snd_preload = 1;
|
||||
@@ -1616,6 +1633,11 @@ bool SetCmdlineParams()
|
||||
Cmdline_fb_explosions = 1;
|
||||
}
|
||||
|
||||
if ( no_batching.found() )
|
||||
{
|
||||
Cmdline_no_batching = true;
|
||||
}
|
||||
|
||||
if ( brieflighting_arg.found() )
|
||||
{
|
||||
Cmdline_brief_lighting = 1;
|
||||
@@ -1641,6 +1663,21 @@ bool SetCmdlineParams()
|
||||
Cmdline_reparse_mainhall = 1;
|
||||
}
|
||||
|
||||
if( shadow_quality_arg.found() )
|
||||
{
|
||||
Cmdline_shadow_quality = shadow_quality_arg.get_int();
|
||||
}
|
||||
|
||||
if( disable_shadows_arg.found() )
|
||||
{
|
||||
Cmdline_shadow_quality = 0;
|
||||
}
|
||||
|
||||
if( no_deferred_lighting_arg.found() )
|
||||
{
|
||||
Cmdline_no_deferred_lighting = 1;
|
||||
}
|
||||
|
||||
if (frame_profile_arg.found() )
|
||||
{
|
||||
Cmdline_frame_profile = true;
|
||||
|
||||
@@ -76,6 +76,9 @@ extern int Cmdline_bloom_intensity;
|
||||
extern bool Cmdline_fxaa;
|
||||
extern int Cmdline_fxaa_preset;
|
||||
extern bool Cmdline_fb_explosions;
|
||||
extern bool Cmdline_no_batching;
|
||||
extern int Cmdline_shadow_quality;
|
||||
extern int Cmdline_no_deferred_lighting;
|
||||
|
||||
// Game Speed related
|
||||
extern int Cmdline_cache_bitmaps;
|
||||
@@ -131,6 +134,7 @@ extern int Cmdline_no_di_mouse;
|
||||
extern int Cmdline_drawelements;
|
||||
extern char* Cmdline_keyboard_layout;
|
||||
extern bool Cmdline_gl_finish;
|
||||
extern bool Cmdline_no_geo_sdr_effects;
|
||||
|
||||
// Developer/Testing related
|
||||
extern char *Cmdline_start_mission;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "graphics/gropengltexture.h"
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "graphics/gropenglstate.h"
|
||||
#include "graphics/gropengldraw.h"
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "cutscene/mvelib.h"
|
||||
@@ -518,12 +519,12 @@ int mve_video_createbuf(ubyte minor, ubyte *data)
|
||||
|
||||
GL_state.Array.BindArrayBuffer(0);
|
||||
|
||||
GL_state.Array.EnableClientVertex();
|
||||
GL_state.Array.VertexPointer(2, GL_FLOAT, sizeof(glVertices[0]), glVertices);
|
||||
vertex_layout vertex_def;
|
||||
|
||||
GL_state.Array.SetActiveClientUnit(0);
|
||||
GL_state.Array.EnableClientTexture();
|
||||
GL_state.Array.TexPointer(2, GL_FLOAT, sizeof(glVertices[0]), &(glVertices[0][2]));
|
||||
vertex_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
|
||||
vertex_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
|
||||
|
||||
opengl_bind_vertex_layout(vertex_def);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -797,9 +798,6 @@ void mve_play(MVESTREAM *mve)
|
||||
void mve_shutdown()
|
||||
{
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
GL_state.Array.DisableClientVertex();
|
||||
GL_state.Array.DisableClientTexture();
|
||||
|
||||
if (mve_scale_video) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
+14
-59
@@ -17,6 +17,7 @@
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "graphics/gropenglshader.h"
|
||||
#include "graphics/gropenglstate.h"
|
||||
#include "graphics/gropengldraw.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "io/key.h"
|
||||
#include "osapi/osapi.h"
|
||||
@@ -331,8 +332,6 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
{
|
||||
float scale_by = 0.0f;
|
||||
|
||||
GLhandleARB shader_id = 0;
|
||||
|
||||
if (video_inited)
|
||||
return;
|
||||
|
||||
@@ -365,52 +364,11 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
return;
|
||||
}
|
||||
|
||||
char *vert = NULL, *frag = NULL;
|
||||
opengl_shader_t new_shader;
|
||||
|
||||
// choose appropriate files
|
||||
char *vert_name = "video-v.sdr";
|
||||
char *frag_name = "video-f.sdr";
|
||||
int sdr_handle = gr_maybe_create_shader(SDR_TYPE_VIDEO_PROCESS, 0);
|
||||
|
||||
mprintf(("Compiling video-processing shader ... \n"));
|
||||
|
||||
// read vertex shader
|
||||
CFILE *cf_shader = cfopen(vert_name, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS);
|
||||
|
||||
if (cf_shader != NULL) {
|
||||
int len = cfilelength(cf_shader);
|
||||
vert = (char*) vm_malloc(len + 1);
|
||||
cfread(vert, len + 1, 1, cf_shader);
|
||||
cfclose(cf_shader);
|
||||
} else {
|
||||
mprintf((" Loading built-in default shader for: %s\n", vert_name));
|
||||
vert = defaults_get_file(vert_name);
|
||||
}
|
||||
|
||||
if(!vert)
|
||||
use_shaders = false;
|
||||
|
||||
// read fragment shader
|
||||
cf_shader = cfopen(frag_name, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS);
|
||||
|
||||
if (cf_shader != NULL) {
|
||||
int len = cfilelength(cf_shader);
|
||||
frag = (char*) vm_malloc(len + 1);
|
||||
cfread(frag, len + 1, 1, cf_shader);
|
||||
cfclose(cf_shader);
|
||||
} else {
|
||||
mprintf((" Loading built-in default shader for: %s\n", frag_name));
|
||||
frag = defaults_get_file(frag_name);
|
||||
}
|
||||
|
||||
if(!vert)
|
||||
use_shaders = false;
|
||||
Verify( vert != NULL );
|
||||
Verify( frag != NULL );
|
||||
|
||||
shader_id = opengl_shader_create(vert, frag);
|
||||
vglUseProgramObjectARB(shader_id);
|
||||
if (!shader_id)
|
||||
if ( sdr_handle >= 0)
|
||||
opengl_shader_set_current(sdr_handle);
|
||||
else
|
||||
use_shaders = false;
|
||||
}
|
||||
|
||||
@@ -532,9 +490,9 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
gl_screenU = i2fl(tinfo->frame_width-1) / i2fl(2048) ;
|
||||
gl_screenV = i2fl(tinfo->frame_height-1) / i2fl(2048);
|
||||
GL_state.Texture.SetShaderMode(GL_TRUE);
|
||||
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "ytex"), 0 );
|
||||
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "utex"), 1 );
|
||||
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "vtex"), 2 );
|
||||
GL_state.Uniform.setUniformi("ytex", 0);
|
||||
GL_state.Uniform.setUniformi("utex", 1);
|
||||
GL_state.Uniform.setUniformi("vtex", 2);
|
||||
}
|
||||
|
||||
glVertices[0][0] = (GLfloat)g_screenX;
|
||||
@@ -559,12 +517,12 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
|
||||
GL_state.Array.BindArrayBuffer(0);
|
||||
|
||||
GL_state.Array.EnableClientVertex();
|
||||
GL_state.Array.VertexPointer(2, GL_FLOAT, sizeof(glVertices[0]), glVertices);
|
||||
vertex_layout vert_def;
|
||||
|
||||
GL_state.Array.SetActiveClientUnit(0);
|
||||
GL_state.Array.EnableClientTexture();
|
||||
GL_state.Array.TexPointer(2, GL_FLOAT, sizeof(glVertices[0]), &(glVertices[0][2]));
|
||||
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
|
||||
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
|
||||
|
||||
opengl_bind_vertex_layout(vert_def);
|
||||
}
|
||||
if(!use_shaders && tinfo->frame_height > 450) {
|
||||
mprintf(("VIDEO: No shader support and hd video is beeing played this can get choppy."));
|
||||
@@ -579,9 +537,6 @@ static void OGG_video_close()
|
||||
}
|
||||
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
GL_state.Array.DisableClientVertex();
|
||||
GL_state.Array.DisableClientTexture();
|
||||
|
||||
if (scale_video) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
@@ -604,7 +559,7 @@ static void OGG_video_close()
|
||||
ytex = utex = vtex = 0;
|
||||
GLtex = 0;
|
||||
GL_state.Texture.SetShaderMode(GL_FALSE);
|
||||
opengl_shader_set_current( 0 );
|
||||
opengl_shader_set_current();
|
||||
}
|
||||
|
||||
if (pixelbuf != NULL) {
|
||||
|
||||
+59
-3
@@ -147,7 +147,7 @@ MONITOR(NumHullDebrisRend)
|
||||
/**
|
||||
* Render debris
|
||||
*/
|
||||
void debris_render(object * obj)
|
||||
void debris_render_DEPRECATED(object * obj)
|
||||
{
|
||||
int i, num, swapped;
|
||||
polymodel *pm;
|
||||
@@ -191,10 +191,10 @@ void debris_render(object * obj)
|
||||
|
||||
if ( db->is_hull ) {
|
||||
MONITOR_INC(NumHullDebrisRend,1);
|
||||
submodel_render( db->model_num, db->submodel_num, &obj->orient, &obj->pos );
|
||||
submodel_render_DEPRECATED( db->model_num, db->submodel_num, &obj->orient, &obj->pos );
|
||||
} else {
|
||||
MONITOR_INC(NumSmallDebrisRend,1);
|
||||
submodel_render( db->model_num, db->submodel_num, &obj->orient, &obj->pos, MR_NO_LIGHTING );
|
||||
submodel_render_DEPRECATED( db->model_num, db->submodel_num, &obj->orient, &obj->pos, MR_NO_LIGHTING );
|
||||
}
|
||||
|
||||
if (tbase != NULL && (swapped!=-1) && pm) {
|
||||
@@ -1094,3 +1094,59 @@ void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs
|
||||
pi->I_body_inv.vec.fvec.xyz.y = 0.0f;
|
||||
pi->I_body_inv.vec.fvec.xyz.z = 12.0f / (pi->mass * (dx*dx + dy*dy));
|
||||
}
|
||||
|
||||
void debris_render(object * obj, draw_list *scene)
|
||||
{
|
||||
int i, num, swapped;
|
||||
polymodel *pm;
|
||||
debris *db;
|
||||
|
||||
|
||||
swapped = -1;
|
||||
pm = NULL;
|
||||
num = obj->instance;
|
||||
|
||||
Assert(num >= 0 && num < MAX_DEBRIS_PIECES);
|
||||
db = &Debris[num];
|
||||
|
||||
Assert(db->flags & DEBRIS_USED);
|
||||
|
||||
texture_info *tbase = NULL;
|
||||
|
||||
model_clear_instance( db->model_num );
|
||||
|
||||
// Swap in a different texture depending on the species
|
||||
if (db->species >= 0)
|
||||
{
|
||||
pm = model_get( db->model_num );
|
||||
|
||||
//WMC - Someday, we should have glowing debris.
|
||||
if ( pm != NULL && (pm->n_textures == 1) ) {
|
||||
tbase = &pm->maps[0].textures[TM_BASE_TYPE];
|
||||
swapped = tbase->GetTexture();
|
||||
tbase->SetTexture(Species_info[db->species].debris_texture.bitmap_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Only render electrical arcs if within 500m of the eye (for a 10m piece)
|
||||
if ( vm_vec_dist_quick( &obj->pos, &Eye_position ) < obj->radius*50.0f ) {
|
||||
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
|
||||
if ( timestamp_valid( db->arc_timestamp[i] ) ) {
|
||||
model_add_arc( db->model_num, db->submodel_num, &db->arc_pts[i][0], &db->arc_pts[i][1], MARC_TYPE_NORMAL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
if ( !db->is_hull ) {
|
||||
render_info.set_flags(MR_NO_LIGHTING);
|
||||
}
|
||||
|
||||
MONITOR_INC(NumHullDebrisRend,1);
|
||||
submodel_render_queue( &render_info, scene, db->model_num, db->submodel_num, &obj->orient, &obj->pos );
|
||||
|
||||
if (tbase != NULL && (swapped!=-1) && pm) {
|
||||
tbase->SetTexture(swapped);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
class object;
|
||||
struct CFILE;
|
||||
class draw_list;
|
||||
|
||||
#define MAX_DEBRIS_ARCS 8 // Must be less than MAX_ARC_EFFECTS in model.h
|
||||
|
||||
@@ -61,7 +62,8 @@ extern int Num_debris_pieces;
|
||||
struct collision_info_struct;
|
||||
|
||||
void debris_init();
|
||||
void debris_render( object * obj );
|
||||
void debris_render_DEPRECATED( object * obj );
|
||||
void debris_render(object * obj, draw_list *scene);
|
||||
void debris_delete( object * obj );
|
||||
void debris_process_post( object * obj, float frame_time);
|
||||
object *debris_create( object * source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force );
|
||||
|
||||
@@ -375,7 +375,7 @@ void fireball_init()
|
||||
|
||||
MONITOR( NumFireballsRend )
|
||||
|
||||
void fireball_render(object * obj)
|
||||
void fireball_render_DEPRECATED(object * obj)
|
||||
{
|
||||
int num;
|
||||
vertex p;
|
||||
@@ -1052,3 +1052,74 @@ float fireball_wormhole_intensity( object *obj )
|
||||
}
|
||||
return rad;
|
||||
}
|
||||
|
||||
void fireball_render(object* obj, draw_list *scene)
|
||||
{
|
||||
int num;
|
||||
vertex p;
|
||||
fireball *fb;
|
||||
|
||||
MONITOR_INC( NumFireballsRend, 1 );
|
||||
|
||||
num = obj->instance;
|
||||
fb = &Fireballs[num];
|
||||
|
||||
if ( Fireballs[num].current_bitmap < 0 )
|
||||
return;
|
||||
|
||||
if ( Cmdline_nohtl ) {
|
||||
g3_rotate_vertex(&p, &obj->pos );
|
||||
} else {
|
||||
g3_transfer_vertex(&p, &obj->pos);
|
||||
}
|
||||
|
||||
switch ( fb->fireball_render_type ) {
|
||||
|
||||
case FIREBALL_MEDIUM_EXPLOSION: {
|
||||
batch_add_bitmap (
|
||||
Fireballs[num].current_bitmap,
|
||||
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD,
|
||||
&p,
|
||||
fb->orient,
|
||||
obj->radius
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case FIREBALL_LARGE_EXPLOSION: {
|
||||
// Make the big explosions rotate with the viewer.
|
||||
batch_add_bitmap_rotated (
|
||||
Fireballs[num].current_bitmap,
|
||||
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD,
|
||||
&p,
|
||||
(i2fl(fb->orient)*PI)/180.0f,
|
||||
obj->radius
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case FIREBALL_WARP_EFFECT: {
|
||||
float percent_life = fb->time_elapsed / fb->total_time;
|
||||
|
||||
float rad;
|
||||
|
||||
// Code to make effect grow/shrink.
|
||||
float t = fb->time_elapsed;
|
||||
|
||||
if ( t < WARPHOLE_GROW_TIME ) {
|
||||
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
|
||||
} else if ( t < fb->total_time - WARPHOLE_GROW_TIME ) {
|
||||
rad = obj->radius;
|
||||
} else {
|
||||
rad = (float)pow((fb->total_time - t)/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
|
||||
}
|
||||
|
||||
warpin_queue_render(scene, obj, &obj->orient, &obj->pos, Fireballs[num].current_bitmap, rad, percent_life, obj->radius, (Fireballs[num].flags & FBF_WARP_3D) );
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
Int3();
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
#define _FIREBALLS_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "model/modelrender.h"
|
||||
|
||||
class object;
|
||||
class ship_info;
|
||||
@@ -76,7 +77,8 @@ typedef struct fireball {
|
||||
// end move
|
||||
|
||||
void fireball_init();
|
||||
void fireball_render(object * obj);
|
||||
void fireball_render_DEPRECATED(object * obj);
|
||||
void fireball_render(object* obj, draw_list *scene);
|
||||
void fireball_delete( object * obj );
|
||||
void fireball_process_post(object * obj, float frame_time);
|
||||
|
||||
@@ -114,6 +116,8 @@ float fireball_wormhole_intensity( object *obj );
|
||||
// internal function to draw warp grid.
|
||||
extern void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d = 0 );
|
||||
|
||||
extern void warpin_queue_render(draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d);
|
||||
|
||||
extern int Warp_model;
|
||||
|
||||
// Goober5000
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "model/model.h"
|
||||
#include "ship/ship.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
|
||||
#include "model/modelrender.h"
|
||||
|
||||
extern int Warp_model;
|
||||
extern int Warp_glow_bitmap;
|
||||
@@ -47,6 +47,25 @@ void draw_face( vertex *v1, vertex *v2, vertex *v3 )
|
||||
|
||||
}
|
||||
|
||||
void warpin_batch_draw_face( int texture, vertex *v1, vertex *v2, vertex *v3 )
|
||||
{
|
||||
vec3d norm;
|
||||
vertex vertlist[3];
|
||||
|
||||
vm_vec_perp(&norm,&v1->world, &v2->world, &v3->world);
|
||||
if ( vm_vec_dot(&norm, &v1->world ) >= 0.0 ) {
|
||||
vertlist[0] = *v3;
|
||||
vertlist[1] = *v2;
|
||||
vertlist[2] = *v1;
|
||||
} else {
|
||||
vertlist[0] = *v1;
|
||||
vertlist[1] = *v2;
|
||||
vertlist[2] = *v3;
|
||||
}
|
||||
|
||||
batch_add_tri(texture, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT, vertlist, 1.0f);
|
||||
}
|
||||
|
||||
void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
|
||||
{
|
||||
vec3d center;
|
||||
@@ -109,15 +128,18 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
|
||||
}
|
||||
|
||||
if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
|
||||
float scale = radius / 25.0f;
|
||||
model_set_warp_globals(scale, scale, scale, texture_bitmap_num, (radius/max_radius) );
|
||||
model_render_params render_info;
|
||||
|
||||
vec3d scale;
|
||||
scale.xyz.z = scale.xyz.y = scale.xyz.x = radius / 25.0f;
|
||||
render_info.set_warp_params(texture_bitmap_num, radius/max_radius, scale);
|
||||
|
||||
float dist = vm_vec_dist_quick( pos, &Eye_position );
|
||||
model_set_detail_level((int)(dist / (radius * 10.0f)));
|
||||
render_info.set_detail_level_lock((int)(dist / (radius * 10.0f)));
|
||||
|
||||
model_render( Warp_model, orient, pos, MR_LOCK_DETAIL | MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL );
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL | MR_NO_BATCH);
|
||||
|
||||
model_set_warp_globals();
|
||||
model_render_immediate( &render_info, Warp_model, orient, pos );
|
||||
} else {
|
||||
float Grid_depth = radius/2.5f;
|
||||
|
||||
@@ -197,3 +219,147 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
|
||||
|
||||
gr_zbuffer_set( saved_gr_zbuffering );
|
||||
}
|
||||
|
||||
void warpin_queue_render(draw_list *scene, object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
|
||||
{
|
||||
vec3d center;
|
||||
vec3d vecs[5];
|
||||
vertex verts[5];
|
||||
|
||||
vm_vec_scale_add( ¢er, pos, &orient->vec.fvec, -(max_radius/2.5f)/3.0f );
|
||||
|
||||
|
||||
if (Warp_glow_bitmap >= 0) {
|
||||
float r = radius;
|
||||
bool render_it = true;
|
||||
|
||||
#define OUT_PERCENT1 0.80f
|
||||
#define OUT_PERCENT2 0.90f
|
||||
|
||||
#define IN_PERCENT1 0.10f
|
||||
#define IN_PERCENT2 0.20f
|
||||
|
||||
if (Cmdline_warp_flash)
|
||||
{
|
||||
if ( (life_percent >= IN_PERCENT1) && (life_percent < IN_PERCENT2) ) {
|
||||
r *= (life_percent - IN_PERCENT1) / (IN_PERCENT2 - IN_PERCENT1);
|
||||
//render_it = true;
|
||||
} else if ( (life_percent >= OUT_PERCENT1) && (life_percent < OUT_PERCENT2) ) {
|
||||
r *= (OUT_PERCENT2 - life_percent) / (OUT_PERCENT2 - OUT_PERCENT1);
|
||||
//render_it = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (render_it) {
|
||||
// Add in noise
|
||||
int noise_frame = fl2i(Missiontime/15.0f) % NOISE_NUM_FRAMES;
|
||||
|
||||
r *= (0.40f + Noise[noise_frame] * 0.30f);
|
||||
|
||||
// Bobboau's warp thingie, toggled by cmdline
|
||||
if (Cmdline_warp_flash) {
|
||||
r += powf((2.0f * life_percent) - 1.0f, 24.0f) * max_radius * 1.5f;
|
||||
}
|
||||
|
||||
vecs[4] = center;
|
||||
verts[4].texture_position.u = 0.5f; verts[4].texture_position.v = 0.5f;
|
||||
|
||||
if (Cmdline_nohtl) {
|
||||
g3_rotate_vertex( &verts[4], &vecs[4] );
|
||||
} else {
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
}
|
||||
|
||||
float alpha = (The_mission.flags & MISSION_FLAG_FULLNEB) ? (1.0f - neb2_get_fog_intensity(obj)) : 1.0f;
|
||||
|
||||
batch_add_bitmap(Warp_glow_bitmap, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT, &verts[4], 0, r, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
|
||||
model_render_params render_info;
|
||||
|
||||
float scale = radius / 25.0f;
|
||||
|
||||
vec3d warp_scale;
|
||||
|
||||
warp_scale.xyz.x = warp_scale.xyz.y = warp_scale.xyz.z = scale;
|
||||
|
||||
float dist = vm_vec_dist_quick( pos, &Eye_position );
|
||||
|
||||
render_info.set_warp_params(texture_bitmap_num, radius/max_radius, warp_scale);
|
||||
render_info.set_detail_level_lock((int)(dist / (radius * 10.0f)));
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL | MR_NO_BATCH);
|
||||
|
||||
model_render_queue( &render_info, scene, Warp_model, orient, pos);
|
||||
} else {
|
||||
float Grid_depth = radius/2.5f;
|
||||
|
||||
// gr_set_bitmap( texture_bitmap_num, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
|
||||
|
||||
vm_vec_scale_add( &vecs[0], ¢er, &orient->vec.uvec, radius );
|
||||
vm_vec_scale_add2( &vecs[0], &orient->vec.rvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[0], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[1], ¢er, &orient->vec.uvec, radius );
|
||||
vm_vec_scale_add2( &vecs[1], &orient->vec.rvec, radius );
|
||||
vm_vec_scale_add2( &vecs[1], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[2], ¢er, &orient->vec.uvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[2], &orient->vec.rvec, radius );
|
||||
vm_vec_scale_add2( &vecs[2], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
vm_vec_scale_add( &vecs[3], ¢er, &orient->vec.uvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[3], &orient->vec.rvec, -radius );
|
||||
vm_vec_scale_add2( &vecs[3], &orient->vec.fvec, Grid_depth );
|
||||
|
||||
// vm_vec_scale_add( &vecs[4], ¢er, &orient->vec.fvec, -Grid_depth );
|
||||
vecs[4] = center;
|
||||
|
||||
verts[0].texture_position.u = 0.01f;
|
||||
verts[0].texture_position.v = 0.01f;
|
||||
|
||||
verts[1].texture_position.u = 0.99f;
|
||||
verts[1].texture_position.v = 0.01f;
|
||||
|
||||
verts[2].texture_position.u = 0.99f;
|
||||
verts[2].texture_position.v = 0.99f;
|
||||
|
||||
verts[3].texture_position.u = 0.01f;
|
||||
verts[3].texture_position.v = 0.99f;
|
||||
|
||||
verts[4].texture_position.u = 0.5f;
|
||||
verts[4].texture_position.v = 0.5f;
|
||||
|
||||
if (Cmdline_nohtl) {
|
||||
g3_rotate_vertex( &verts[0], &vecs[0] );
|
||||
g3_rotate_vertex( &verts[1], &vecs[1] );
|
||||
g3_rotate_vertex( &verts[2], &vecs[2] );
|
||||
g3_rotate_vertex( &verts[3], &vecs[3] );
|
||||
g3_rotate_vertex( &verts[4], &vecs[4] );
|
||||
} else {
|
||||
g3_transfer_vertex( &verts[0], &vecs[0] );
|
||||
g3_transfer_vertex( &verts[1], &vecs[1] );
|
||||
g3_transfer_vertex( &verts[2], &vecs[2] );
|
||||
g3_transfer_vertex( &verts[3], &vecs[3] );
|
||||
g3_transfer_vertex( &verts[4], &vecs[4] );
|
||||
}
|
||||
|
||||
warpin_batch_draw_face( texture_bitmap_num, &verts[0], &verts[4], &verts[1] );
|
||||
warpin_batch_draw_face( texture_bitmap_num, &verts[1], &verts[4], &verts[2] );
|
||||
warpin_batch_draw_face( texture_bitmap_num, &verts[4], &verts[3], &verts[2] );
|
||||
warpin_batch_draw_face( texture_bitmap_num, &verts[0], &verts[3], &verts[4] );
|
||||
}
|
||||
|
||||
if (Warp_ball_bitmap > -1 && Cmdline_warp_flash == 1) {
|
||||
//flash_ball warp_ball(20, .1f,.25f, &vmd_z_vector, &vmd_zero_vector, 4.0f, 0.5f);
|
||||
flash_ball warp_ball(20, .1f,.25f, &orient->vec.fvec, pos, 4.0f, 0.5f);
|
||||
|
||||
float adg = (2.0f * life_percent) - 1.0f;
|
||||
float pct = (powf(adg, 4.0f) - powf(adg, 128.0f)) * 4.0f;
|
||||
|
||||
if (pct > 0.00001f) {
|
||||
warp_ball.render(Warp_ball_bitmap, max_radius * pct * 0.5f, adg * adg, adg * adg * 6.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
-10
@@ -702,6 +702,7 @@ void render_one_model_briefing_screen(object *objp)
|
||||
void render_one_model_nohtl(object *objp)
|
||||
{
|
||||
int j, z;
|
||||
uint debug_flags = 0;
|
||||
object *o2;
|
||||
|
||||
Assert(objp->type != OBJ_NONE);
|
||||
@@ -755,11 +756,11 @@ void render_one_model_nohtl(object *objp)
|
||||
}
|
||||
|
||||
if(Show_dock_points){
|
||||
j |= MR_BAY_PATHS;
|
||||
debug_flags |= MR_DEBUG_BAY_PATHS;
|
||||
}
|
||||
|
||||
if(Show_paths_fred){
|
||||
j |= MR_SHOW_PATHS;
|
||||
debug_flags |= MR_DEBUG_PATHS;
|
||||
}
|
||||
|
||||
z = objp->instance;
|
||||
@@ -768,12 +769,19 @@ void render_one_model_nohtl(object *objp)
|
||||
|
||||
// if (!viewpoint || OBJ_INDEX(objp) != cur_object_index)
|
||||
{
|
||||
model_render_params render_info;
|
||||
|
||||
if (Fred_outline) {
|
||||
model_set_outline_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
|
||||
model_render(Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos, j | MR_SHOW_OUTLINE, -1, -1, Ships[z].ship_replacement_textures);
|
||||
render_info.set_flags(j | MR_SHOW_OUTLINE | MR_NO_TEXTURING | MR_NO_LIGHTING);
|
||||
render_info.set_outline_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
|
||||
} else {
|
||||
model_render(Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos, j, -1, -1, Ships[z].ship_replacement_textures);
|
||||
render_info.set_flags(j);
|
||||
}
|
||||
|
||||
render_info.set_debug_flags(debug_flags);
|
||||
render_info.set_replacement_textures(Ships[z].ship_replacement_textures);
|
||||
|
||||
model_render_immediate(&render_info, Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -831,6 +839,7 @@ void render_one_model_nohtl(object *objp)
|
||||
void render_one_model_htl(object *objp)
|
||||
{
|
||||
int j, z;
|
||||
uint debug_flags = 0;
|
||||
object *o2;
|
||||
|
||||
Assert(objp->type != OBJ_NONE);
|
||||
@@ -878,6 +887,7 @@ void render_one_model_htl(object *objp)
|
||||
// build flags
|
||||
if ((Show_ship_models || Show_outlines) && ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START))){
|
||||
g3_start_instance_matrix(&Eye_position, &Eye_matrix, 0);
|
||||
|
||||
if (Show_ship_models){
|
||||
j = MR_NORMAL;
|
||||
} else {
|
||||
@@ -885,11 +895,11 @@ void render_one_model_htl(object *objp)
|
||||
}
|
||||
|
||||
if(Show_dock_points){
|
||||
j |= MR_BAY_PATHS;
|
||||
debug_flags |= MR_DEBUG_BAY_PATHS;
|
||||
}
|
||||
|
||||
if(Show_paths_fred){
|
||||
j |= MR_SHOW_PATHS;
|
||||
debug_flags |= MR_DEBUG_PATHS;
|
||||
}
|
||||
|
||||
z = objp->instance;
|
||||
@@ -905,13 +915,19 @@ void render_one_model_htl(object *objp)
|
||||
j |= MR_FULL_DETAIL;
|
||||
}
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
if (Fred_outline) {
|
||||
model_set_outline_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
|
||||
j |= MR_SHOW_OUTLINE_HTL;
|
||||
render_info.set_outline_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
|
||||
j |= MR_SHOW_OUTLINE_HTL | MR_NO_LIGHTING | MR_NO_POLYS | MR_NO_TEXTURING;
|
||||
}
|
||||
|
||||
render_info.set_flags(j);
|
||||
render_info.set_debug_flags(debug_flags);
|
||||
render_info.set_replacement_textures(Ships[z].ship_replacement_textures);
|
||||
|
||||
g3_done_instance(0);
|
||||
model_render(Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos, j, -1, -1, Ships[z].ship_replacement_textures);
|
||||
model_render_immediate(&render_info, Ship_info[Ships[z].ship_info_index].model_num, &objp->orient, &objp->pos);
|
||||
} else {
|
||||
int r = 0, g = 0, b = 0;
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "globalincs/version.h"
|
||||
#include "globalincs/mspdb_callstack.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/shadows.h"
|
||||
#include "hud/hud.h"
|
||||
#include "hud/hudconfig.h"
|
||||
#include "hud/hudescort.h"
|
||||
@@ -2020,7 +2021,8 @@ void game_init()
|
||||
armor_init();
|
||||
ai_init();
|
||||
ai_profiles_init(); // Goober5000
|
||||
weapon_init();
|
||||
weapon_init();
|
||||
glowpoint_init();
|
||||
ship_init(); // read in ships.tbl
|
||||
|
||||
player_init();
|
||||
@@ -2175,7 +2177,7 @@ void game_show_framerate()
|
||||
gr_set_color_fast(&HUD_color_debug);
|
||||
|
||||
if (Cmdline_frame_profile) {
|
||||
gr_string(20, 100 + line_height, profile_output, GR_RESIZE_NONE);
|
||||
gr_string(20, 100 + line_height, profile_output.c_str(), GR_RESIZE_NONE);
|
||||
}
|
||||
|
||||
if (Show_framerate) {
|
||||
@@ -3666,7 +3668,8 @@ DCF_BOOL( subspace, Game_subspace_effect )
|
||||
void clip_frame_view();
|
||||
|
||||
// Does everything needed to render a frame
|
||||
extern SCP_vector<object*> effect_ships;
|
||||
extern SCP_vector<object*> effect_ships;
|
||||
extern SCP_vector<object*> transparent_objects;
|
||||
void game_render_frame( camid cid )
|
||||
{
|
||||
|
||||
@@ -3715,7 +3718,7 @@ void game_render_frame( camid cid )
|
||||
// Note: environment mapping gets disabled when rendering to texture; if you change
|
||||
// this, make sure that the current render target gets restored right afterwards!
|
||||
if ( Cmdline_env && !Env_cubemap_drawn && gr_screen.rendering_to_texture == -1 ) {
|
||||
setup_environment_mapping(cid);
|
||||
PROFILE("Environment Mapping", setup_environment_mapping(cid));
|
||||
|
||||
if ( !Dynamic_environment ) {
|
||||
Env_cubemap_drawn = true;
|
||||
@@ -3740,15 +3743,13 @@ void game_render_frame( camid cid )
|
||||
stars_draw(1,1,1,0,0);
|
||||
}
|
||||
|
||||
bool draw_viewer_last = false;
|
||||
obj_render_all(obj_render, &draw_viewer_last);
|
||||
|
||||
// Why do we not show the shield effect in these modes? Seems ok.
|
||||
//if (!(Viewer_mode & (VM_EXTERNAL | VM_SLEWED | VM_CHASE | VM_DEAD_VIEW))) {
|
||||
render_shields();
|
||||
//}
|
||||
PROFILE("Build Shadow Map", shadows_render_all(Proj_fov, &Eye_matrix, &Eye_position));
|
||||
PROFILE("Render Scene", obj_render_queue_all());
|
||||
|
||||
PROFILE("Particles", particle_render_all()); // render particles after everything else.
|
||||
render_shields();
|
||||
|
||||
PROFILE("Trails", trail_render_all()); // render missilie trails after everything else.
|
||||
PROFILE("Particles", particle_render_all()); // render particles after everything else.
|
||||
|
||||
#ifdef DYN_CLIP_DIST
|
||||
if(!Cmdline_nohtl)
|
||||
@@ -3761,8 +3762,6 @@ void game_render_frame( camid cid )
|
||||
#endif
|
||||
|
||||
beam_render_all(); // render all beam weapons
|
||||
|
||||
PROFILE("Trails", trail_render_all()); // render missilie trails after everything else.
|
||||
|
||||
// render nebula lightning
|
||||
nebl_render_all();
|
||||
@@ -3770,14 +3769,25 @@ void game_render_frame( camid cid )
|
||||
// render local player nebula
|
||||
neb2_render_player();
|
||||
|
||||
gr_copy_effect_texture();
|
||||
|
||||
// render all ships with shader effects on them
|
||||
SCP_vector<object*>::iterator obji = effect_ships.begin();
|
||||
for(;obji != effect_ships.end();++obji)
|
||||
ship_render(*obji);
|
||||
{
|
||||
obj_render(*obji);
|
||||
}
|
||||
effect_ships.clear();
|
||||
|
||||
batch_render_distortion_map_bitmaps();
|
||||
|
||||
Shadow_override = true;
|
||||
//Draw the viewer 'cause we didn't before.
|
||||
//This is so we can change the minimum clipping distance without messing everything up.
|
||||
if(draw_viewer_last && Viewer_obj)
|
||||
if ( Viewer_obj
|
||||
&& (Viewer_obj->type == OBJ_SHIP)
|
||||
&& (Ship_info[Ships[Viewer_obj->instance].ship_info_index].flags2 & SIF2_SHOW_SHIP_MODEL)
|
||||
&& (!Viewer_mode || (Viewer_mode & VM_PADLOCK_ANY) || (Viewer_mode & VM_OTHER_SHIP) || (Viewer_mode & VM_TRACK)) )
|
||||
{
|
||||
gr_post_process_save_zbuffer();
|
||||
ship_render_show_ship_cockpit(Viewer_obj);
|
||||
@@ -3813,10 +3823,10 @@ void game_render_frame( camid cid )
|
||||
gr_end_proj_matrix();
|
||||
gr_end_view_matrix();
|
||||
}
|
||||
|
||||
Shadow_override = false;
|
||||
//================ END OF 3D RENDERING STUFF ====================
|
||||
|
||||
gr_scene_texture_end();
|
||||
PROFILE("Post Process", gr_scene_texture_end());
|
||||
|
||||
extern int Multi_display_netinfo;
|
||||
if(Multi_display_netinfo){
|
||||
@@ -7919,8 +7929,11 @@ void Time_model( int modelnum )
|
||||
g3_set_view_matrix( &eye_pos, &eye_orient, VIEWER_ZOOM_DEFAULT );
|
||||
|
||||
model_clear_instance( modelnum );
|
||||
|
||||
model_render_params render_info;
|
||||
render_info.set_detail_level_lock(0);
|
||||
model_set_detail_level(0); // use highest detail level
|
||||
model_render( modelnum, &model_orient, &model_pos, MR_LOCK_DETAIL); //|MR_NO_POLYS );
|
||||
model_render_immediate( &render_info, modelnum, &model_orient, &model_pos ); //|MR_NO_POLYS );
|
||||
|
||||
g3_end_frame();
|
||||
// gr_flip();
|
||||
|
||||
+748
-214
File diff suppressed because it is too large.
Load diff
+105
-48
@@ -36,10 +36,10 @@
|
||||
SCP_vector<profile_sample> samples;
|
||||
SCP_vector<profile_sample_history> history;
|
||||
|
||||
float start_profile_time = 0.0f;
|
||||
float end_profile_time = 0.0f;
|
||||
uint start_profile_time = 0;
|
||||
uint end_profile_time = 0;
|
||||
|
||||
char profile_output[2048] = "";
|
||||
SCP_string profile_output;
|
||||
std::ofstream profiling_file;
|
||||
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ std::ofstream profiling_file;
|
||||
*/
|
||||
void profile_init()
|
||||
{
|
||||
start_profile_time = f2fl(timer_get_fixed_seconds());
|
||||
start_profile_time = timer_get_high_res_microseconds(); //f2fl(timer_get_fixed_seconds());
|
||||
|
||||
if (Cmdline_profile_write_file)
|
||||
{
|
||||
@@ -77,16 +77,30 @@ void profile_deinit()
|
||||
* profile_end with the same argument.
|
||||
* @param name A globally unique string that will be displayed in the HUD readout
|
||||
*/
|
||||
void profile_begin(char* name)
|
||||
void profile_begin(const char* name)
|
||||
{
|
||||
if (Cmdline_frame_profile)
|
||||
{
|
||||
int parent = -1;
|
||||
for (int i = 0; i < (int)samples.size(); i++) {
|
||||
if ( !samples[i].open_profiles ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
samples[i].num_children++;
|
||||
|
||||
if (samples[i].num_children == 1) {
|
||||
// this is our direct parent for this new sample
|
||||
parent = i;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < (int)samples.size(); i++) {
|
||||
if(samples[i].valid && !strcmp(samples[i].name, name) ) {
|
||||
if( !strcmp(samples[i].name.c_str(), name) && samples[i].parent == parent ) {
|
||||
// found the profile sample
|
||||
samples[i].open_profiles++;
|
||||
samples[i].profile_instances++;
|
||||
samples[i].start_time = f2fl(timer_get_fixed_seconds());
|
||||
samples[i].start_time = timer_get_high_res_microseconds(); //f2fl(timer_get_fixed_seconds());
|
||||
Assert(samples[i].open_profiles == 1); // max 1 open at once
|
||||
return;
|
||||
}
|
||||
@@ -95,13 +109,14 @@ void profile_begin(char* name)
|
||||
// create a new profile sample
|
||||
profile_sample new_sample;
|
||||
|
||||
strcpy_s(new_sample.name, name);
|
||||
new_sample.valid = true;
|
||||
new_sample.name = SCP_string(name);
|
||||
new_sample.open_profiles = 1;
|
||||
new_sample.profile_instances = 1;
|
||||
new_sample.accumulator = 0.0f;
|
||||
new_sample.start_time = f2fl(timer_get_fixed_seconds());
|
||||
new_sample.children_sample_time = 0.0f;
|
||||
new_sample.accumulator = 0;
|
||||
new_sample.start_time = timer_get_high_res_microseconds(); //f2fl(timer_get_fixed_seconds());
|
||||
new_sample.children_sample_time = 0;
|
||||
new_sample.num_children = 0;
|
||||
new_sample.parent = parent;
|
||||
|
||||
samples.push_back(new_sample);
|
||||
}
|
||||
@@ -112,28 +127,38 @@ void profile_begin(char* name)
|
||||
* to profile_begin
|
||||
* @param name A globally unique string that will be displayed in the HUD readout
|
||||
*/
|
||||
void profile_end(char* name)
|
||||
void profile_end(const char* name)
|
||||
{
|
||||
if (Cmdline_frame_profile) {
|
||||
int num_parents = 0;
|
||||
int child_of = -1;
|
||||
|
||||
for(int i = 0; i < (int)samples.size(); i++) {
|
||||
if(samples[i].valid && !strcmp(samples[i].name, name) ) {
|
||||
for ( int i = 0; i < (int)samples.size(); i++ ) {
|
||||
if ( samples[i].open_profiles ) {
|
||||
if ( samples[i].num_children == 1 ) {
|
||||
child_of = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < (int)samples.size(); i++ ) {
|
||||
if ( !strcmp(samples[i].name.c_str(), name) && samples[i].parent == child_of ) {
|
||||
int inner = 0;
|
||||
int parent = -1;
|
||||
float end_time = f2fl(timer_get_fixed_seconds());
|
||||
uint end_time = timer_get_high_res_microseconds(); //f2fl(timer_get_fixed_seconds());
|
||||
samples[i].open_profiles--;
|
||||
|
||||
// count all parents and find the immediate parent
|
||||
while(inner < (int)samples.size() && samples[inner].valid) {
|
||||
if(samples[inner].open_profiles > 0) {
|
||||
while ( inner < (int)samples.size() ) {
|
||||
if ( samples[inner].open_profiles > 0 ) {
|
||||
// found a parent (any open profiles are parents)
|
||||
num_parents++;
|
||||
|
||||
if(parent < 0) {
|
||||
if (parent < 0) {
|
||||
// replace invalid parent (index)
|
||||
parent = inner;
|
||||
} else if(samples[inner].start_time >= samples[parent].start_time) {
|
||||
}
|
||||
else if (samples[inner].start_time >= samples[parent].start_time) {
|
||||
// replace with more immediate parent
|
||||
parent = inner;
|
||||
}
|
||||
@@ -144,15 +169,22 @@ void profile_end(char* name)
|
||||
// remember the current number of parents of the sample
|
||||
samples[i].num_parents = num_parents;
|
||||
|
||||
if(parent >= 0) {
|
||||
if ( parent >= 0 ) {
|
||||
// record this time in children_sample_time (add it in)
|
||||
samples[parent].children_sample_time += end_time - samples[i].start_time;
|
||||
}
|
||||
|
||||
// save sample time in accumulator
|
||||
samples[i].accumulator += end_time - samples[i].start_time;
|
||||
|
||||
return;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)samples.size(); i++) {
|
||||
if (samples[i].open_profiles) {
|
||||
samples[i].num_children--;
|
||||
samples[i].num_children = MAX(samples[i].num_children, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,21 +196,21 @@ void profile_end(char* name)
|
||||
void profile_dump_output()
|
||||
{
|
||||
if (Cmdline_frame_profile) {
|
||||
end_profile_time = f2fl(timer_get_fixed_seconds());
|
||||
end_profile_time = timer_get_high_res_microseconds(); //f2fl(timer_get_fixed_seconds());
|
||||
|
||||
if (Cmdline_profile_write_file)
|
||||
{
|
||||
profiling_file << end_profile_time << ";" << (end_profile_time - start_profile_time) << std::endl;
|
||||
}
|
||||
|
||||
strcpy_s(profile_output, "");
|
||||
strcat(profile_output, " Avg : Min : Max : # : Profile Name\n");
|
||||
strcat(profile_output, "----------------------------------------\n");
|
||||
profile_output.clear();
|
||||
profile_output += " Avg : Min : Max : # : Profile Name\n";
|
||||
profile_output += "----------------------------------------\n";
|
||||
|
||||
for(int i = 0; i < (int)samples.size(); i++) {
|
||||
float sample_time, percent_time, avg_time, min_time, max_time;
|
||||
char line[256], name[256], indented_name[256];
|
||||
char avg[16], min[16], max[16], num[16];
|
||||
uint sample_time;
|
||||
float percent_time, avg_time, min_time, max_time;
|
||||
uint avg_micro_seconds, min_micro_seconds, max_micro_seconds;
|
||||
|
||||
Assert(samples[i].open_profiles == 0);
|
||||
|
||||
@@ -187,32 +219,38 @@ void profile_dump_output()
|
||||
if (end_profile_time == start_profile_time) {
|
||||
percent_time = 0.0f;
|
||||
} else {
|
||||
percent_time = (sample_time / (end_profile_time - start_profile_time)) *100.0f;
|
||||
percent_time = (i2fl(sample_time) / i2fl(end_profile_time - start_profile_time)) *100.0f;
|
||||
}
|
||||
|
||||
avg_micro_seconds = min_micro_seconds = max_micro_seconds = sample_time;
|
||||
avg_time = min_time = max_time = percent_time;
|
||||
|
||||
// add new measurement into the history and get avg, min, and max
|
||||
store_profile_in_history(samples[i].name, percent_time);
|
||||
get_profile_from_history(samples[i].name, &avg_time, &min_time, &max_time);
|
||||
store_profile_in_history(samples[i].name, percent_time, sample_time);
|
||||
get_profile_from_history(samples[i].name, &avg_time, &min_time, &max_time, &avg_micro_seconds, &min_micro_seconds, &max_micro_seconds);
|
||||
|
||||
// format the data
|
||||
sprintf(avg, "%3.1f", avg_time);
|
||||
sprintf(min, "%3.1f", min_time);
|
||||
sprintf(max, "%3.1f", max_time);
|
||||
char avg[64], min[64], max[64], num[64];
|
||||
|
||||
sprintf(avg, "%3.1f%% (%3.1fms)", avg_time, i2fl(avg_micro_seconds)*0.001f);
|
||||
sprintf(min, "%3.1f%% (%3.1fms)", min_time, i2fl(min_micro_seconds)*0.001f);
|
||||
sprintf(max, "%3.1f%% (%3.1fms)", max_time, i2fl(max_micro_seconds)*0.001f);
|
||||
sprintf(num, "%3d", samples[i].profile_instances);
|
||||
|
||||
strcpy(indented_name, samples[i].name);
|
||||
SCP_string indented_name(samples[i].name);
|
||||
|
||||
for(uint indent = 0; indent < samples[i].num_parents; indent++) {
|
||||
sprintf(name, " %s", indented_name);
|
||||
strcpy_s(indented_name, name);
|
||||
indented_name = ">" + indented_name;
|
||||
}
|
||||
|
||||
sprintf(line, "%5s : %5s : %5s : %3s : %s\n", avg, min, max, num, indented_name);
|
||||
strcat(profile_output, line);
|
||||
char line[256];
|
||||
sprintf(line, "%5s : %5s : %5s : %3s : ", avg, min, max, num);
|
||||
|
||||
profile_output += line + indented_name + "\n";
|
||||
}
|
||||
|
||||
samples.clear();
|
||||
start_profile_time = f2fl(timer_get_fixed_seconds());
|
||||
start_profile_time = timer_get_high_res_microseconds(); //f2fl(timer_get_fixed_seconds());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +260,7 @@ void profile_dump_output()
|
||||
* @param name The globally unique name for this profile (see profile_begin()/profile_end())
|
||||
* @param percent How much time the profiled section took to execute (as a percentage of overall frametime)
|
||||
*/
|
||||
void store_profile_in_history(char* name, float percent)
|
||||
void store_profile_in_history(SCP_string &name, float percent, uint time)
|
||||
{
|
||||
float old_ratio;
|
||||
float new_ratio = 0.8f * f2fl(Frametime);
|
||||
@@ -234,9 +272,10 @@ void store_profile_in_history(char* name, float percent)
|
||||
old_ratio = 1.0f - new_ratio;
|
||||
|
||||
for(int i = 0; i < (int)history.size(); i++) {
|
||||
if( history[i].valid && !strcmp(history[i].name, name) ) {
|
||||
if( history[i].valid && history[i].name == name ) {
|
||||
// found the sample
|
||||
history[i].avg = (history[i].avg * old_ratio) + (percent * new_ratio);
|
||||
history[i].avg_micro_sec = (history[i].avg_micro_sec * old_ratio) + (time * new_ratio);
|
||||
|
||||
if( percent < history[i].min ) {
|
||||
history[i].min = percent;
|
||||
@@ -244,11 +283,24 @@ void store_profile_in_history(char* name, float percent)
|
||||
history[i].min = (history[i].min*old_ratio) + (percent*new_ratio);
|
||||
}
|
||||
|
||||
if( time < history[i].min_micro_sec ) {
|
||||
history[i].min_micro_sec = time;
|
||||
} else {
|
||||
history[i].min_micro_sec = (history[i].min_micro_sec*old_ratio) + (time*new_ratio);
|
||||
}
|
||||
|
||||
if( percent > history[i].max) {
|
||||
history[i].max = percent;
|
||||
} else {
|
||||
history[i].max = (history[i].max * old_ratio) + (percent * new_ratio);
|
||||
}
|
||||
|
||||
if( time > history[i].max_micro_sec) {
|
||||
history[i].max_micro_sec = time;
|
||||
} else {
|
||||
history[i].max_micro_sec = (history[i].max_micro_sec * old_ratio) + (time * new_ratio);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -256,9 +308,10 @@ void store_profile_in_history(char* name, float percent)
|
||||
// add to history
|
||||
profile_sample_history new_history;
|
||||
|
||||
strcpy_s(new_history.name, name);
|
||||
new_history.name = name;
|
||||
new_history.valid = true;
|
||||
new_history.avg = new_history.min = new_history.max = percent;
|
||||
new_history.avg_micro_sec = new_history.min_micro_sec = new_history.max_micro_sec = time;
|
||||
|
||||
history.push_back(new_history);
|
||||
}
|
||||
@@ -270,15 +323,19 @@ void store_profile_in_history(char* name, float percent)
|
||||
* @param min Pointer to a float in which the minimum value will be stored (or 0.0 if no value has been saved)
|
||||
* @param max Pointer to a float in which the maximum value will be stored (or 0.0 if no value has been saved)
|
||||
*/
|
||||
void get_profile_from_history(char* name, float* avg, float* min, float* max)
|
||||
void get_profile_from_history(SCP_string &name, float* avg, float* min, float* max, uint *avg_micro_sec, uint *min_micro_sec, uint *max_micro_sec)
|
||||
{
|
||||
for(int i = 0; i < (int)history.size(); i++) {
|
||||
if(!strcmp(history[i].name, name)) {
|
||||
for ( int i = 0; i < (int)history.size(); i++ ) {
|
||||
if ( history[i].name == name ) {
|
||||
*avg = history[i].avg;
|
||||
*min = history[i].min;
|
||||
*max = history[i].max;
|
||||
*avg_micro_sec = history[i].avg_micro_sec;
|
||||
*min_micro_sec = history[i].min_micro_sec;
|
||||
*max_micro_sec = history[i].max_micro_sec;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*avg = *min = *max = 0.0f;
|
||||
}
|
||||
+42
-36
@@ -73,6 +73,15 @@ typedef struct ccodes {
|
||||
|
||||
struct vertex;
|
||||
|
||||
typedef struct vec4 {
|
||||
union {
|
||||
struct {
|
||||
float x,y,z,w;
|
||||
} xyzw;
|
||||
float a1d[4];
|
||||
};
|
||||
} vec4;
|
||||
|
||||
/** Represents a point in 3d space.
|
||||
|
||||
Note: this is a struct, not a class, so no member functions. */
|
||||
@@ -112,6 +121,16 @@ typedef struct matrix {
|
||||
};
|
||||
} matrix;
|
||||
|
||||
typedef struct matrix4 {
|
||||
union {
|
||||
struct {
|
||||
vec4 rvec, uvec, fvec, pos;
|
||||
} vec;
|
||||
float a2d[4][4];
|
||||
float a1d[16];
|
||||
};
|
||||
} matrix4;
|
||||
|
||||
typedef struct uv_pair {
|
||||
float u,v;
|
||||
} uv_pair;
|
||||
@@ -167,6 +186,29 @@ typedef struct effect_vertex {
|
||||
ubyte r, g, b, a;
|
||||
} effect_vertex;
|
||||
|
||||
struct fx_vertex {
|
||||
vec3d position;
|
||||
vec3d normal;
|
||||
uv_pair tex_coord;
|
||||
float size;
|
||||
ubyte r, g, b, a;
|
||||
};
|
||||
|
||||
struct particle_pnt {
|
||||
vec3d position;
|
||||
float size;
|
||||
vec3d up;
|
||||
};
|
||||
|
||||
struct trail_shader_info {
|
||||
vec3d pos;
|
||||
vec3d fvec;
|
||||
|
||||
float intensity;
|
||||
float width;
|
||||
uv_pair tex_coord;
|
||||
};
|
||||
|
||||
//def_list
|
||||
typedef struct flag_def_list {
|
||||
char *name;
|
||||
@@ -446,42 +488,6 @@ extern int game_busy_callback( void (*callback)(int count), int delta_step = -1
|
||||
// Call whenever loading to display cursor
|
||||
extern void game_busy(const char *filename = NULL);
|
||||
|
||||
//=========================================================
|
||||
// Functions to profile frame performance
|
||||
|
||||
typedef struct profile_sample {
|
||||
bool valid;
|
||||
uint profile_instances;
|
||||
int open_profiles;
|
||||
char name[256];
|
||||
float start_time;
|
||||
float accumulator;
|
||||
float children_sample_time;
|
||||
uint num_parents;
|
||||
} profile_sample;
|
||||
|
||||
typedef struct profile_sample_history {
|
||||
bool valid;
|
||||
char name[256];
|
||||
float avg;
|
||||
float min;
|
||||
float max;
|
||||
} profile_sample_history;
|
||||
|
||||
extern char profile_output[2048];
|
||||
|
||||
void profile_init();
|
||||
void profile_deinit();
|
||||
void profile_begin(char* name);
|
||||
void profile_end(char* name);
|
||||
void profile_dump_output();
|
||||
void store_profile_in_history(char* name, float percent);
|
||||
void get_profile_from_history(char* name, float* avg, float* min, float* max);
|
||||
|
||||
// Helper macro to encapsulate a single function call in a profile_begin()/profile_end() pair.
|
||||
#define PROFILE(name, function) { profile_begin(name); function; profile_end(name); }
|
||||
|
||||
|
||||
//=========================================================
|
||||
// Functions to monitor performance
|
||||
#ifndef NDEBUG
|
||||
|
||||
@@ -77,6 +77,7 @@ bool Glowpoint_use_depth_buffer = true;
|
||||
bool GLSL_override = false;
|
||||
bool PostProcessing_override = false;
|
||||
bool Teamcolor_override = false;
|
||||
bool Shadow_override = false;
|
||||
|
||||
// Values used for noise for thruster animations
|
||||
float Noise[NOISE_NUM_FRAMES] = {
|
||||
|
||||
@@ -144,6 +144,7 @@ extern bool Glowpoint_use_depth_buffer;
|
||||
extern bool GLSL_override;
|
||||
extern bool PostProcessing_override;
|
||||
extern bool Teamcolor_override;
|
||||
extern bool Shadow_override;
|
||||
|
||||
// game skill levels
|
||||
#define NUM_SKILL_LEVELS 5
|
||||
@@ -192,6 +193,63 @@ void detail_level_set(int level);
|
||||
// Returns the current detail level or -1 if custom.
|
||||
int current_detail_level();
|
||||
|
||||
//=========================================================
|
||||
// Functions to profile frame performance
|
||||
|
||||
typedef struct profile_sample {
|
||||
uint profile_instances;
|
||||
int open_profiles;
|
||||
//char name[256];
|
||||
SCP_string name;
|
||||
uint start_time; // in microseconds
|
||||
uint accumulator;
|
||||
uint children_sample_time;
|
||||
uint num_parents;
|
||||
uint num_children;
|
||||
int parent;
|
||||
} profile_sample;
|
||||
|
||||
typedef struct profile_sample_history {
|
||||
bool valid;
|
||||
//char name[256];
|
||||
SCP_string name;
|
||||
float avg;
|
||||
float min;
|
||||
float max;
|
||||
uint avg_micro_sec;
|
||||
uint min_micro_sec;
|
||||
uint max_micro_sec;
|
||||
} profile_sample_history;
|
||||
|
||||
extern SCP_string profile_output;
|
||||
|
||||
void profile_init();
|
||||
void profile_deinit();
|
||||
void profile_begin(const char* name);
|
||||
void profile_begin(SCP_string &output_handle, const char* name);
|
||||
void profile_end(const char* name);
|
||||
void profile_dump_output();
|
||||
void store_profile_in_history(SCP_string &name, float percent, uint time);
|
||||
void get_profile_from_history(SCP_string &name, float* avg, float* min, float* max, uint *avg_micro_sec, uint *min_micro_sec, uint *max_micro_sec);
|
||||
|
||||
class profile_auto
|
||||
{
|
||||
SCP_string name;
|
||||
public:
|
||||
profile_auto(const char* profile_name): name(profile_name)
|
||||
{
|
||||
profile_begin(profile_name);
|
||||
}
|
||||
|
||||
~profile_auto()
|
||||
{
|
||||
profile_end(name.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
// Helper macro to encapsulate a single function call in a profile_begin()/profile_end() pair.
|
||||
#define PROFILE(name, function) { profile_begin(name); function; profile_end(name); }
|
||||
|
||||
//====================================================================================
|
||||
// Memory stuff from WinDebug.cpp
|
||||
extern int TotalRam;
|
||||
|
||||
@@ -159,6 +159,7 @@ bool operator!=(const SCP_vm_allocator<T1>&, const SCP_vm_allocator<T2>&) throw(
|
||||
#define SCP_deque std::deque
|
||||
#define SCP_vector std::vector
|
||||
#define SCP_list std::list
|
||||
#define SCP_unordered_map std::unordered_map
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+313
-3
@@ -15,6 +15,7 @@
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "osapi/osapi.h"
|
||||
@@ -31,9 +32,9 @@
|
||||
#include "parse/scripting.h"
|
||||
#include "gamesequence/gamesequence.h" //WMC - for scripting hooks in gr_flip()
|
||||
#include "io/keycontrol.h" // m!m
|
||||
#include "graphics/gropengldraw.h"
|
||||
#include "debugconsole/console.h"
|
||||
#include "debugconsole/console.h"
|
||||
|
||||
#include "io/timer.h"
|
||||
|
||||
#if defined(SCP_UNIX) && !defined(__APPLE__)
|
||||
#if ( SDL_VERSION_ATLEAST(1, 2, 7) )
|
||||
@@ -102,6 +103,10 @@ float Gr_save_menu_zoomed_offset_X = 0.0f, Gr_save_menu_zoomed_offset_Y = 0.0f;
|
||||
|
||||
bool Save_custom_screen_size;
|
||||
|
||||
vertex_layout Point_particle_vertex_layout;
|
||||
vertex_layout Effect_vertex_layout;
|
||||
vertex_layout Trail_vertex_layout;
|
||||
|
||||
void gr_set_screen_scale(int w, int h, int zoom_w, int zoom_h, int max_w, int max_h, bool force_stretch)
|
||||
{
|
||||
bool do_zoom = zoom_w > 0 && zoom_h > 0 && (zoom_w != w || zoom_h != h);
|
||||
@@ -1454,6 +1459,20 @@ int poly_list::find_first_vertex(int idx)
|
||||
return idx;
|
||||
}
|
||||
|
||||
int poly_list::find_first_vertex_fast(int idx)
|
||||
{
|
||||
uint* first_idx = std::lower_bound(sorted_indices, sorted_indices + n_verts, idx, finder(this, NULL, NULL));
|
||||
|
||||
if ( first_idx == sorted_indices + n_verts ) {
|
||||
// if this happens then idx was never in the index list to begin with which is not good
|
||||
mprintf(("Sorted index list missing index %d!", idx));
|
||||
Int3();
|
||||
return idx;
|
||||
}
|
||||
|
||||
return *first_idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list (plist) find the index within the indexed list that the vert at position idx within list is at
|
||||
*/
|
||||
@@ -1479,6 +1498,17 @@ int poly_list::find_index(poly_list *plist, int idx)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int poly_list::find_index_fast(poly_list *plist, int idx)
|
||||
{
|
||||
// searching for an out of bounds index using the finder means we're trying to find the vert and norm we're passing into the finder instance
|
||||
uint* first_idx = std::lower_bound(sorted_indices, sorted_indices + n_verts, n_verts, finder(this, &plist->vert[idx], &plist->norm[idx]));
|
||||
|
||||
if (first_idx == sorted_indices + n_verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return *first_idx;
|
||||
}
|
||||
|
||||
void poly_list::allocate(int _verts)
|
||||
{
|
||||
@@ -1500,6 +1530,16 @@ void poly_list::allocate(int _verts)
|
||||
tsb = NULL;
|
||||
}
|
||||
|
||||
if ( submodels != NULL ) {
|
||||
vm_free(submodels);
|
||||
submodels = NULL;
|
||||
}
|
||||
|
||||
if ( sorted_indices != NULL ) {
|
||||
vm_free(sorted_indices);
|
||||
sorted_indices = NULL;
|
||||
}
|
||||
|
||||
if (_verts) {
|
||||
vert = (vertex*)vm_malloc(sizeof(vertex) * _verts);
|
||||
norm = (vec3d*)vm_malloc(sizeof(vec3d) * _verts);
|
||||
@@ -1507,6 +1547,12 @@ void poly_list::allocate(int _verts)
|
||||
if (Cmdline_normal) {
|
||||
tsb = (tsb_t*)vm_malloc(sizeof(tsb_t) * _verts);
|
||||
}
|
||||
|
||||
if ( Use_GLSL >= 3 ) {
|
||||
submodels = (int*)vm_malloc(sizeof(int) * _verts);
|
||||
}
|
||||
|
||||
sorted_indices = (uint*)vm_malloc(sizeof(uint) * _verts);
|
||||
}
|
||||
|
||||
n_verts = 0;
|
||||
@@ -1529,6 +1575,16 @@ poly_list::~poly_list()
|
||||
vm_free(tsb);
|
||||
tsb = NULL;
|
||||
}
|
||||
|
||||
if ( submodels != NULL ) {
|
||||
vm_free(submodels);
|
||||
submodels = NULL;
|
||||
}
|
||||
|
||||
if (sorted_indices != NULL) {
|
||||
vm_free(sorted_indices);
|
||||
sorted_indices = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void poly_list::calculate_tangent()
|
||||
@@ -1626,6 +1682,9 @@ void poly_list::make_index_buffer(SCP_vector<int> &vertex_list)
|
||||
int j, z = 0;
|
||||
ubyte *nverts_good = NULL;
|
||||
|
||||
uint t0, t1;
|
||||
t0 = timer_get_milliseconds();
|
||||
|
||||
// calculate tangent space data (must be done early)
|
||||
calculate_tangent();
|
||||
|
||||
@@ -1640,14 +1699,20 @@ void poly_list::make_index_buffer(SCP_vector<int> &vertex_list)
|
||||
|
||||
vertex_list.reserve(n_verts);
|
||||
|
||||
generate_sorted_index_list();
|
||||
|
||||
for (j = 0; j < n_verts; j++) {
|
||||
if (find_first_vertex(j) == j) {
|
||||
if (find_first_vertex_fast(j) == j) {
|
||||
nverts++;
|
||||
nverts_good[j] = 1;
|
||||
vertex_list.push_back(j);
|
||||
}
|
||||
}
|
||||
|
||||
t1 = timer_get_milliseconds();
|
||||
|
||||
mprintf(("Index Buffer created in %d milliseconds\n", t1-t0));
|
||||
|
||||
// if there is nothig to change then bail
|
||||
if (n_verts == nverts) {
|
||||
if (nverts_good != NULL) {
|
||||
@@ -1672,6 +1737,10 @@ void poly_list::make_index_buffer(SCP_vector<int> &vertex_list)
|
||||
buffer_list_internal.tsb[z] = tsb[j];
|
||||
}
|
||||
|
||||
if ( Use_GLSL >= 3 ) {
|
||||
buffer_list_internal.submodels[z] = submodels[j];
|
||||
}
|
||||
|
||||
buffer_list_internal.n_verts++;
|
||||
z++;
|
||||
}
|
||||
@@ -1682,6 +1751,8 @@ void poly_list::make_index_buffer(SCP_vector<int> &vertex_list)
|
||||
vm_free(nverts_good);
|
||||
}
|
||||
|
||||
buffer_list_internal.generate_sorted_index_list();
|
||||
|
||||
(*this) = buffer_list_internal;
|
||||
}
|
||||
|
||||
@@ -1696,11 +1767,98 @@ poly_list& poly_list::operator = (poly_list &other_list)
|
||||
memcpy(tsb, other_list.tsb, sizeof(tsb_t) * other_list.n_verts);
|
||||
}
|
||||
|
||||
if ( Use_GLSL >= 3 ) {
|
||||
memcpy(submodels, other_list.submodels, sizeof(int) * other_list.n_verts);
|
||||
}
|
||||
|
||||
memcpy(sorted_indices, other_list.sorted_indices, sizeof(uint) * other_list.n_verts);
|
||||
|
||||
n_verts = other_list.n_verts;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void poly_list::generate_sorted_index_list()
|
||||
{
|
||||
for ( uint j = 0; j < n_verts; ++j) {
|
||||
sorted_indices[j] = j;
|
||||
}
|
||||
|
||||
std::sort(sorted_indices, sorted_indices + n_verts, finder(this));
|
||||
}
|
||||
|
||||
bool poly_list::finder::operator()(const uint a, const uint b)
|
||||
{
|
||||
vertex *vert_a;
|
||||
vertex *vert_b;
|
||||
vec3d *norm_a;
|
||||
vec3d *norm_b;
|
||||
|
||||
Assert(search_list != NULL);
|
||||
|
||||
if ( a == search_list->n_verts ) {
|
||||
Assert(vert_to_find != NULL);
|
||||
Assert(norm_to_find != NULL);
|
||||
Assert(a != b);
|
||||
|
||||
vert_a = vert_to_find;
|
||||
norm_a = norm_to_find;
|
||||
} else {
|
||||
vert_a = &search_list->vert[a];
|
||||
norm_a = &search_list->norm[a];
|
||||
}
|
||||
|
||||
if ( b == search_list->n_verts ) {
|
||||
Assert(vert_to_find != NULL);
|
||||
Assert(norm_to_find != NULL);
|
||||
Assert(a != b);
|
||||
|
||||
vert_b = vert_to_find;
|
||||
norm_b = norm_to_find;
|
||||
} else {
|
||||
vert_b = &search_list->vert[b];
|
||||
norm_b = &search_list->norm[b];
|
||||
}
|
||||
|
||||
if (norm_a->xyz.x != norm_b->xyz.x) {
|
||||
return norm_a->xyz.x < norm_b->xyz.x;
|
||||
}
|
||||
|
||||
if (norm_a->xyz.y != norm_b->xyz.y) {
|
||||
return norm_a->xyz.y < norm_b->xyz.y;
|
||||
}
|
||||
|
||||
if (norm_a->xyz.z != norm_b->xyz.z) {
|
||||
return norm_a->xyz.z < norm_b->xyz.z;
|
||||
}
|
||||
|
||||
if (vert_a->world.xyz.x != vert_b->world.xyz.x) {
|
||||
return vert_a->world.xyz.x < vert_b->world.xyz.x;
|
||||
}
|
||||
|
||||
if (vert_a->world.xyz.y != vert_b->world.xyz.y) {
|
||||
return vert_a->world.xyz.y < vert_b->world.xyz.y;
|
||||
}
|
||||
|
||||
if (vert_a->world.xyz.z != vert_b->world.xyz.z) {
|
||||
return vert_a->world.xyz.z < vert_b->world.xyz.z;
|
||||
}
|
||||
|
||||
if (vert_a->texture_position.u != vert_b->texture_position.u) {
|
||||
return vert_a->texture_position.u < vert_b->texture_position.u;
|
||||
}
|
||||
|
||||
if ( vert_a->texture_position.v != vert_b->texture_position.v ) {
|
||||
return vert_a->texture_position.v < vert_b->texture_position.v;
|
||||
}
|
||||
|
||||
if ( !compare_indices ) {
|
||||
return vert_a->texture_position.v < vert_b->texture_position.v;
|
||||
} else {
|
||||
return a < b;
|
||||
}
|
||||
}
|
||||
|
||||
void gr_shield_icon(coord2d coords[6], int resize_mode)
|
||||
{
|
||||
if (gr_screen.mode == GR_STUB) {
|
||||
@@ -1783,3 +1941,155 @@ void gr_flip()
|
||||
|
||||
gr_screen.gf_flip();
|
||||
}
|
||||
|
||||
uint gr_determine_model_shader_flags(
|
||||
bool lighting,
|
||||
bool fog,
|
||||
bool textured,
|
||||
bool in_shadow_map,
|
||||
bool thruster_scale,
|
||||
bool transform,
|
||||
bool team_color,
|
||||
int tmap_flags,
|
||||
int spec_map,
|
||||
int glow_map,
|
||||
int normal_map,
|
||||
int height_map,
|
||||
int env_map,
|
||||
int misc_map
|
||||
) {
|
||||
uint shader_flags = 0;
|
||||
|
||||
if ( Use_GLSL > 1 ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_CLIP;
|
||||
}
|
||||
|
||||
if ( transform ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_TRANSFORM;
|
||||
}
|
||||
|
||||
if ( in_shadow_map ) {
|
||||
// if we're building the shadow map, we likely only need the flags here and above so bail
|
||||
shader_flags |= SDR_FLAG_MODEL_SHADOW_MAP;
|
||||
|
||||
return shader_flags;
|
||||
}
|
||||
|
||||
// setup shader flags for the things that we want/need
|
||||
if ( lighting ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_LIGHT;
|
||||
}
|
||||
|
||||
if ( fog ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_FOG;
|
||||
}
|
||||
|
||||
if ( tmap_flags & TMAP_ANIMATED_SHADER ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_ANIMATED;
|
||||
}
|
||||
|
||||
if ( textured ) {
|
||||
if ( !Basemap_override ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_DIFFUSE_MAP;
|
||||
}
|
||||
|
||||
if ( glow_map > 0 ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_GLOW_MAP;
|
||||
}
|
||||
|
||||
if ( lighting ) {
|
||||
if ( ( spec_map > 0 ) && !Specmap_override ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_SPEC_MAP;
|
||||
|
||||
if ( ( env_map > 0 ) && !Envmap_override ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_ENV_MAP;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( normal_map > 0) && !Normalmap_override ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_NORMAL_MAP;
|
||||
}
|
||||
|
||||
if ( ( height_map > 0) && !Heightmap_override ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_HEIGHT_MAP;
|
||||
}
|
||||
|
||||
if ( Cmdline_shadow_quality && !in_shadow_map && !Shadow_override) {
|
||||
shader_flags |= SDR_FLAG_MODEL_SHADOWS;
|
||||
}
|
||||
}
|
||||
|
||||
if ( misc_map > 0 ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_MISC_MAP;
|
||||
}
|
||||
|
||||
if ( team_color ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_TEAMCOLOR;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Deferred_lighting ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_DEFERRED;
|
||||
}
|
||||
|
||||
if ( thruster_scale ) {
|
||||
shader_flags |= SDR_FLAG_MODEL_THRUSTER;
|
||||
}
|
||||
|
||||
return shader_flags;
|
||||
}
|
||||
|
||||
void gr_build_vertex_layouts()
|
||||
{
|
||||
// build vertex definition for geometry shader particles
|
||||
ubyte* ptr = NULL;
|
||||
int offset = 0;
|
||||
int size = 0;
|
||||
|
||||
size = sizeof(particle_pnt);
|
||||
offset = 0;
|
||||
|
||||
Point_particle_vertex_layout.add_vertex_component(vertex_format_data::POSITION3, size, ptr + offset);
|
||||
offset += sizeof(vec3d);
|
||||
|
||||
Point_particle_vertex_layout.add_vertex_component(vertex_format_data::RADIUS, size, ptr + offset);
|
||||
offset += sizeof(float);
|
||||
|
||||
Point_particle_vertex_layout.add_vertex_component(vertex_format_data::UVEC, size, ptr + offset);
|
||||
offset += sizeof(vec3d);
|
||||
|
||||
size = sizeof(effect_vertex);
|
||||
offset = 0;
|
||||
|
||||
// build vertex definition for general shader drawn billboards
|
||||
Effect_vertex_layout.add_vertex_component(vertex_format_data::POSITION3, size, ptr + offset);
|
||||
offset += sizeof(vec3d);
|
||||
|
||||
Effect_vertex_layout.add_vertex_component(vertex_format_data::TEX_COORD, size, ptr + offset);
|
||||
offset += sizeof(uv_pair);
|
||||
|
||||
Effect_vertex_layout.add_vertex_component(vertex_format_data::RADIUS, size, ptr + offset);
|
||||
offset += sizeof(float);
|
||||
|
||||
Effect_vertex_layout.add_vertex_component(vertex_format_data::COLOR4, size, ptr + offset);
|
||||
offset += sizeof(float);
|
||||
|
||||
size = sizeof(trail_shader_info);
|
||||
offset = 0;
|
||||
|
||||
// build vertex definition for geometry shader generated trails
|
||||
Trail_vertex_layout.add_vertex_component(vertex_format_data::POSITION3, size, ptr + offset);
|
||||
offset += sizeof(vec3d);
|
||||
|
||||
Trail_vertex_layout.add_vertex_component(vertex_format_data::FVEC, size, ptr + offset);
|
||||
offset += sizeof(vec3d);
|
||||
|
||||
Trail_vertex_layout.add_vertex_component(vertex_format_data::INTENSITY, size, ptr + offset);
|
||||
offset += sizeof(float);
|
||||
|
||||
Trail_vertex_layout.add_vertex_component(vertex_format_data::RADIUS, size, ptr + offset);
|
||||
offset += sizeof(float);
|
||||
|
||||
Trail_vertex_layout.add_vertex_component(vertex_format_data::TEX_COORD, size, ptr + offset);
|
||||
offset += sizeof(uv_pair);
|
||||
}
|
||||
+205
-45
@@ -27,21 +27,47 @@ extern int Gr_inited;
|
||||
extern int gr_zbuffering, gr_zbuffering_mode;
|
||||
extern int gr_global_zbuffering;
|
||||
|
||||
enum shader_type {
|
||||
SDR_TYPE_MODEL,
|
||||
SDR_TYPE_EFFECT_PARTICLE,
|
||||
SDR_TYPE_EFFECT_DISTORTION,
|
||||
SDR_TYPE_POST_PROCESS_MAIN,
|
||||
SDR_TYPE_POST_PROCESS_BLUR,
|
||||
SDR_TYPE_POST_PROCESS_BRIGHTPASS,
|
||||
SDR_TYPE_POST_PROCESS_FXAA,
|
||||
SDR_TYPE_POST_PROCESS_FXAA_PREPASS,
|
||||
SDR_TYPE_POST_PROCESS_LIGHTSHAFTS,
|
||||
SDR_TYPE_DEFERRED_LIGHTING,
|
||||
SDR_TYPE_DEFERRED_CLEAR,
|
||||
SDR_TYPE_VIDEO_PROCESS,
|
||||
|
||||
NUM_SHADER_TYPES
|
||||
};
|
||||
|
||||
// Shader flags
|
||||
#define SDR_FLAG_LIGHT (1<<0)
|
||||
#define SDR_FLAG_FOG (1<<1)
|
||||
#define SDR_FLAG_DIFFUSE_MAP (1<<2)
|
||||
#define SDR_FLAG_GLOW_MAP (1<<3)
|
||||
#define SDR_FLAG_SPEC_MAP (1<<4)
|
||||
#define SDR_FLAG_NORMAL_MAP (1<<5)
|
||||
#define SDR_FLAG_HEIGHT_MAP (1<<6)
|
||||
#define SDR_FLAG_ENV_MAP (1<<7)
|
||||
#define SDR_FLAG_ANIMATED (1<<8)
|
||||
#define SDR_FLAG_SOFT_QUAD (1<<9)
|
||||
#define SDR_FLAG_DISTORTION (1<<10)
|
||||
#define SDR_FLAG_MISC_MAP (1<<11)
|
||||
#define SDR_FLAG_TEAMCOLOR (1<<12)
|
||||
#define SDR_FLAG_THRUSTER (1<<13)
|
||||
#define SDR_FLAG_MODEL_LIGHT (1<<0)
|
||||
#define SDR_FLAG_MODEL_FOG (1<<1)
|
||||
#define SDR_FLAG_MODEL_DIFFUSE_MAP (1<<2)
|
||||
#define SDR_FLAG_MODEL_GLOW_MAP (1<<3)
|
||||
#define SDR_FLAG_MODEL_SPEC_MAP (1<<4)
|
||||
#define SDR_FLAG_MODEL_NORMAL_MAP (1<<5)
|
||||
#define SDR_FLAG_MODEL_HEIGHT_MAP (1<<6)
|
||||
#define SDR_FLAG_MODEL_ENV_MAP (1<<7)
|
||||
#define SDR_FLAG_MODEL_ANIMATED (1<<8)
|
||||
#define SDR_FLAG_MODEL_MISC_MAP (1<<9)
|
||||
#define SDR_FLAG_MODEL_TEAMCOLOR (1<<10)
|
||||
#define SDR_FLAG_MODEL_TRANSFORM (1<<11)
|
||||
#define SDR_FLAG_MODEL_DEFERRED (1<<12)
|
||||
#define SDR_FLAG_MODEL_SHADOW_MAP (1<<13)
|
||||
#define SDR_FLAG_MODEL_GEOMETRY (1<<14)
|
||||
#define SDR_FLAG_MODEL_SHADOWS (1<<15)
|
||||
#define SDR_FLAG_MODEL_THRUSTER (1<<16)
|
||||
#define SDR_FLAG_MODEL_CLIP (1<<17)
|
||||
|
||||
#define SDR_FLAG_PARTICLE_POINT_GEN (1<<0)
|
||||
|
||||
#define SDR_FLAG_BLUR_HORIZONTAL (1<<0)
|
||||
#define SDR_FLAG_BLUR_VERTICAL (1<<1)
|
||||
|
||||
// stencil buffering stuff
|
||||
extern int gr_stencil_mode;
|
||||
@@ -100,10 +126,23 @@ typedef struct tsb_t {
|
||||
* This should be basicly just like it is in the VB
|
||||
* a list of triangles and their associated normals
|
||||
*/
|
||||
class poly_list
|
||||
{
|
||||
class poly_list {
|
||||
// helper function struct that let's us sort the indices.
|
||||
// an instance is fed into std::sort and std::lower_bound.
|
||||
// overloaded operator() is used for the comparison function.
|
||||
struct finder {
|
||||
poly_list* search_list;
|
||||
bool compare_indices;
|
||||
vertex* vert_to_find;
|
||||
vec3d* norm_to_find;
|
||||
|
||||
finder(poly_list* _search_list): search_list(_search_list), compare_indices(true), vert_to_find(NULL), norm_to_find(NULL) {}
|
||||
finder(poly_list* _search_list, vertex* _vert, vec3d* _norm): search_list(_search_list), compare_indices(false), vert_to_find(_vert), norm_to_find(_norm) {}
|
||||
|
||||
bool operator()(const uint a, const uint b);
|
||||
};
|
||||
public:
|
||||
poly_list(): n_verts(0), vert(NULL), norm(NULL), tsb(NULL), currently_allocated(0) {}
|
||||
poly_list(): n_verts(0), vert(NULL), norm(NULL), tsb(NULL), submodels(NULL), sorted_indices(NULL), currently_allocated(0) {}
|
||||
~poly_list();
|
||||
poly_list& operator = (poly_list&);
|
||||
|
||||
@@ -114,15 +153,19 @@ public:
|
||||
vertex *vert;
|
||||
vec3d *norm;
|
||||
tsb_t *tsb;
|
||||
int *submodels;
|
||||
|
||||
uint *sorted_indices;
|
||||
|
||||
int find_index(poly_list *plist, int idx);
|
||||
|
||||
int find_index_fast(poly_list *plist, int idx);
|
||||
private:
|
||||
int currently_allocated;
|
||||
int find_first_vertex(int idx);
|
||||
int find_first_vertex_fast(int idx);
|
||||
void generate_sorted_index_list();
|
||||
};
|
||||
|
||||
|
||||
class colored_vector
|
||||
{
|
||||
public:
|
||||
@@ -178,20 +221,35 @@ public:
|
||||
}
|
||||
|
||||
// Constructor
|
||||
|
||||
buffer_data() :
|
||||
flags(0), texture(-1), n_verts(0), index_offset(0),
|
||||
i_first(1), i_last(0), index(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
buffer_data(int n_vrts) :
|
||||
flags(0), texture(-1), n_verts(n_vrts), index_offset(0),
|
||||
i_first(1), i_last(0)
|
||||
i_first(1), i_last(0), index(NULL)
|
||||
{
|
||||
index = new(std::nothrow) uint[n_verts];
|
||||
if ( n_verts > 0 ) {
|
||||
index = new(std::nothrow) uint[n_verts];
|
||||
} else {
|
||||
index = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy-constructor
|
||||
buffer_data(const buffer_data& other)
|
||||
{
|
||||
index = new(std::nothrow) uint[other.n_verts];
|
||||
for (size_t i=0; i < (size_t) other.n_verts; i++)
|
||||
{
|
||||
index[i] = other.index[i];
|
||||
if ( other.index ) {
|
||||
index = new(std::nothrow) uint[other.n_verts];
|
||||
for (size_t i=0; i < (size_t) other.n_verts; i++)
|
||||
{
|
||||
index[i] = other.index[i];
|
||||
}
|
||||
} else {
|
||||
index = NULL;
|
||||
}
|
||||
|
||||
flags = other.flags;
|
||||
@@ -209,12 +267,16 @@ public:
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
delete [] index;
|
||||
|
||||
index = new(std::nothrow) uint[rhs.n_verts];
|
||||
for (size_t i=0; i < (size_t) rhs.n_verts; i++)
|
||||
{
|
||||
index[i] = rhs.index[i];
|
||||
if ( index ) {
|
||||
delete [] index;
|
||||
}
|
||||
|
||||
if ( rhs.index && rhs.n_verts > 0 ) {
|
||||
index = new(std::nothrow) uint[rhs.n_verts];
|
||||
for (size_t i=0; i < (size_t) rhs.n_verts; i++)
|
||||
{
|
||||
index[i] = rhs.index[i];
|
||||
}
|
||||
}
|
||||
|
||||
flags = rhs.flags;
|
||||
@@ -507,16 +569,17 @@ typedef struct screen {
|
||||
|
||||
int (*gf_create_buffer)();
|
||||
bool (*gf_pack_buffer)(const int buffer_id, vertex_buffer *vb);
|
||||
bool (*gf_config_buffer)(const int buffer_id, vertex_buffer *vb);
|
||||
bool (*gf_config_buffer)(const int buffer_id, vertex_buffer *vb, bool update_ibuffer_only);
|
||||
void (*gf_destroy_buffer)(int);
|
||||
void (*gf_set_buffer)(int);
|
||||
void (*gf_render_buffer)(int, const vertex_buffer*, int, int);
|
||||
|
||||
void (*gf_update_buffer_object)(int handle, uint size, void* data);
|
||||
void (*gf_update_transform_buffer)(void* data, uint size);
|
||||
void (*gf_set_transform_buffer_offset)(int offset);
|
||||
|
||||
int (*gf_create_stream_buffer)();
|
||||
void (*gf_update_stream_buffer)(int buffer, effect_vertex *buffer_data, uint size);
|
||||
void (*gf_render_stream_buffer)(int offset, int n_verts, int flags);
|
||||
void (*gf_render_stream_buffer_start)(int buffer_id);
|
||||
void (*gf_render_stream_buffer_end)();
|
||||
void (*gf_render_stream_buffer)(int buffer_handle, int offset, int n_verts, int flags);
|
||||
|
||||
int (*gf_make_flat_buffer)(poly_list*);
|
||||
int (*gf_make_line_buffer)(line_list*);
|
||||
@@ -551,11 +614,18 @@ typedef struct screen {
|
||||
void (*gf_post_process_end)();
|
||||
void (*gf_post_process_save_zbuffer)();
|
||||
|
||||
void (*gf_deferred_lighting_begin)();
|
||||
void (*gf_deferred_lighting_end)();
|
||||
void (*gf_deferred_lighting_finish)();
|
||||
|
||||
void (*gf_scene_texture_begin)();
|
||||
void (*gf_scene_texture_end)();
|
||||
void (*gf_copy_effect_texture)();
|
||||
|
||||
void (*gf_lighting)(bool,bool);
|
||||
void (*gf_set_light_factor)(float);
|
||||
void (*gf_center_alpha)(int);
|
||||
void (*gf_set_thrust_scale)(float);
|
||||
|
||||
void (*gf_start_clip_plane)();
|
||||
void (*gf_end_clip_plane)();
|
||||
@@ -573,15 +643,19 @@ typedef struct screen {
|
||||
void (*gf_line_htl)(vec3d *start, vec3d* end);
|
||||
void (*gf_sphere_htl)(float rad);
|
||||
|
||||
int (*gf_maybe_create_shader)(int flags);
|
||||
int (*gf_maybe_create_shader)(shader_type type, unsigned int flags);
|
||||
|
||||
void (*gf_flush_data_states)();
|
||||
void (*gf_set_animated_effect)(int effect, float timer);
|
||||
|
||||
void (*gf_set_team_color)(const SCP_string &team, const SCP_string &secondaryteam, fix timestamp, int fadetime);
|
||||
void (*gf_enable_team_color)();
|
||||
void (*gf_disable_team_color)();
|
||||
void (*gf_clear_states)();
|
||||
|
||||
void (*gf_set_team_color)(team_color *colors);
|
||||
|
||||
void (*gf_update_texture)(int bitmap_handle, int bpp, ubyte* data, int width, int height);
|
||||
void (*gf_get_bitmap_from_texture)(void* data_out, int bitmap_num);
|
||||
|
||||
void (*gf_shadow_map_start)(matrix4 *shadow_view_matrix, matrix *light_matrix);
|
||||
void (*gf_shadow_map_end)();
|
||||
} screen;
|
||||
|
||||
// handy macro
|
||||
@@ -836,8 +910,11 @@ __inline void gr_render_buffer(int start, const vertex_buffer *bufferp, int texi
|
||||
(*gr_screen.gf_render_buffer)(start, bufferp, texi, flags);
|
||||
}
|
||||
|
||||
#define gr_update_buffer_object GR_CALL(*gr_screen.gf_update_buffer_object)
|
||||
#define gr_update_transform_buffer GR_CALL(*gr_screen.gf_update_transform_buffer)
|
||||
#define gr_set_transform_buffer_offset GR_CALL(*gr_screen.gf_set_transform_buffer_offset)
|
||||
|
||||
#define gr_create_stream_buffer GR_CALL(*gr_screen.gf_create_stream_buffer)
|
||||
#define gr_update_stream_buffer GR_CALL(*gr_screen.gf_update_stream_buffer)
|
||||
#define gr_render_stream_buffer GR_CALL(*gr_screen.gf_render_stream_buffer)
|
||||
#define gr_render_stream_buffer_start GR_CALL(*gr_screen.gf_render_stream_buffer_start)
|
||||
#define gr_render_stream_buffer_end GR_CALL(*gr_screen.gf_render_stream_buffer_end)
|
||||
@@ -866,6 +943,7 @@ __inline void gr_render_buffer(int start, const vertex_buffer *bufferp, int texi
|
||||
|
||||
#define gr_scene_texture_begin GR_CALL(*gr_screen.gf_scene_texture_begin)
|
||||
#define gr_scene_texture_end GR_CALL(*gr_screen.gf_scene_texture_end)
|
||||
#define gr_copy_effect_texture GR_CALL(*gr_screen.gf_copy_effect_texture)
|
||||
|
||||
#define gr_post_process_set_effect GR_CALL(*gr_screen.gf_post_process_set_effect)
|
||||
#define gr_post_process_set_defaults GR_CALL(*gr_screen.gf_post_process_set_defaults)
|
||||
@@ -873,8 +951,14 @@ __inline void gr_render_buffer(int start, const vertex_buffer *bufferp, int texi
|
||||
#define gr_post_process_end GR_CALL(*gr_screen.gf_post_process_end)
|
||||
#define gr_post_process_save_zbuffer GR_CALL(*gr_screen.gf_post_process_save_zbuffer)
|
||||
|
||||
#define gr_deferred_lighting_begin GR_CALL(*gr_screen.gf_deferred_lighting_begin)
|
||||
#define gr_deferred_lighting_end GR_CALL(*gr_screen.gf_deferred_lighting_end)
|
||||
#define gr_deferred_lighting_finish GR_CALL(*gr_screen.gf_deferred_lighting_finish)
|
||||
|
||||
#define gr_set_lighting GR_CALL(*gr_screen.gf_lighting)
|
||||
#define gr_set_light_factor GR_CALL(*gr_screen.gf_set_light_factor)
|
||||
#define gr_center_alpha GR_CALL(*gr_screen.gf_center_alpha)
|
||||
#define gr_set_thrust_scale GR_CALL(*gr_screen.gf_set_thrust_scale)
|
||||
|
||||
#define gr_start_clip GR_CALL(*gr_screen.gf_start_clip_plane)
|
||||
#define gr_end_clip GR_CALL(*gr_screen.gf_end_clip_plane)
|
||||
@@ -897,13 +981,17 @@ __inline void gr_render_buffer(int start, const vertex_buffer *bufferp, int texi
|
||||
#define gr_sphere_htl GR_CALL(*gr_screen.gf_sphere_htl)
|
||||
|
||||
#define gr_maybe_create_shader GR_CALL(*gr_screen.gf_maybe_create_shader)
|
||||
#define gr_set_animated_effect GR_CALL(*gr_screen.gf_set_animated_effect)
|
||||
|
||||
#define gr_flush_data_states GR_CALL(*gr_screen.gf_flush_data_states)
|
||||
#define gr_clear_states GR_CALL(*gr_screen.gf_clear_states)
|
||||
|
||||
#define gr_set_team_color GR_CALL(*gr_screen.gf_set_team_color)
|
||||
#define gr_disable_team_color GR_CALL(*gr_screen.gf_disable_team_color)
|
||||
|
||||
#define gr_update_texture GR_CALL(*gr_screen.gf_update_texture)
|
||||
#define gr_get_bitmap_from_texture GR_CALL(*gr_screen.gf_get_bitmap_from_texture)
|
||||
|
||||
#define gr_shadow_map_start GR_CALL(*gr_screen.gf_shadow_map_start)
|
||||
#define gr_shadow_map_end GR_CALL(*gr_screen.gf_shadow_map_end)
|
||||
|
||||
// color functions
|
||||
void gr_get_color( int *r, int *g, int b );
|
||||
@@ -916,6 +1004,23 @@ void gr_set_color_fast(color *dst);
|
||||
void gr_create_shader(shader *shade, ubyte r, ubyte g, ubyte b, ubyte c);
|
||||
void gr_set_shader(shader *shade);
|
||||
|
||||
uint gr_determine_model_shader_flags(
|
||||
bool lighting,
|
||||
bool fog,
|
||||
bool textured,
|
||||
bool in_shadow_map,
|
||||
bool thruster_scale,
|
||||
bool transform,
|
||||
bool team_color_set,
|
||||
int tmap_flags,
|
||||
int spec_map,
|
||||
int glow_map,
|
||||
int normal_map,
|
||||
int height_map,
|
||||
int env_map,
|
||||
int misc_map
|
||||
);
|
||||
|
||||
// new bitmap functions
|
||||
void gr_bitmap(int x, int y, int resize_mode = GR_RESIZE_FULL);
|
||||
void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u1, float _v1, int resize_mode = GR_RESIZE_FULL);
|
||||
@@ -942,7 +1047,62 @@ void gr_pline_special(SCP_vector<vec3d> *pts, int thickness,int resize_mode=GR_R
|
||||
#define VB_FLAG_UV4 (1<<8)
|
||||
#define VB_FLAG_TANGENT (1<<9)
|
||||
#define VB_FLAG_LARGE_INDEX (1<<10)
|
||||
#define VB_FLAG_MODEL_ID (1<<11)
|
||||
#define VB_FLAG_TRANS (1<<12)
|
||||
|
||||
struct vertex_format_data
|
||||
{
|
||||
enum vertex_format {
|
||||
POSITION4,
|
||||
POSITION3,
|
||||
POSITION2,
|
||||
SCREEN_POS,
|
||||
COLOR3,
|
||||
COLOR4,
|
||||
TEX_COORD,
|
||||
NORMAL,
|
||||
TANGENT,
|
||||
MODEL_ID,
|
||||
RADIUS,
|
||||
FVEC,
|
||||
UVEC,
|
||||
INTENSITY
|
||||
};
|
||||
|
||||
vertex_format format_type;
|
||||
uint stride;
|
||||
void *data_src;
|
||||
|
||||
vertex_format_data(vertex_format i_format_type, uint i_stride, void *i_data_src) :
|
||||
format_type(i_format_type), stride(i_stride), data_src(i_data_src) {}
|
||||
};
|
||||
|
||||
class vertex_layout
|
||||
{
|
||||
SCP_vector<vertex_format_data> Vertex_components;
|
||||
|
||||
uint Vertex_mask;
|
||||
public:
|
||||
vertex_layout(): Vertex_mask(0) {}
|
||||
|
||||
uint get_num_vertex_components() { return Vertex_components.size(); }
|
||||
|
||||
vertex_format_data* get_vertex_component(uint index) { return &Vertex_components[index]; }
|
||||
|
||||
bool resident_vertex_format(vertex_format_data::vertex_format format_type) { return Vertex_mask & (1 << format_type) ? true : false; }
|
||||
|
||||
void add_vertex_component(vertex_format_data::vertex_format format_type, uint stride, void* src)
|
||||
{
|
||||
if ( resident_vertex_format(format_type) ) {
|
||||
// we already have a vertex component of this format type
|
||||
return;
|
||||
}
|
||||
|
||||
Vertex_mask |= (1 << format_type);
|
||||
Vertex_components.push_back(vertex_format_data(format_type, stride, src));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void gr_clear_shaders_cache();
|
||||
|
||||
#endif
|
||||
+593
-150
@@ -350,9 +350,9 @@ void geometry_batcher::draw_quad(vertex* verts)
|
||||
P[1] = verts[1];
|
||||
P[2] = verts[2];
|
||||
|
||||
P[0] = verts[0];
|
||||
P[2] = verts[2];
|
||||
P[3] = verts[3];
|
||||
P[3] = verts[0];
|
||||
P[4] = verts[2];
|
||||
P[5] = verts[3];
|
||||
|
||||
n_to_render += 2;
|
||||
use_radius = false;
|
||||
@@ -523,7 +523,7 @@ float geometry_batcher::draw_laser(vec3d *p0, float width1, vec3d *p1, float wid
|
||||
void geometry_batcher::render(int flags, float radius)
|
||||
{
|
||||
if (n_to_render) {
|
||||
if ( (Use_Shaders_for_effect_rendering && Use_GLSL > 2 && ((flags & TMAP_FLAG_SOFT_QUAD) && Cmdline_softparticles)) || (flags & TMAP_FLAG_DISTORTION) || ((flags & TMAP_FLAG_DISTORTION_THRUSTER) && use_radius) ) {
|
||||
if ( Use_Shaders_for_effect_rendering && (flags & TMAP_FLAG_SOFT_QUAD || flags & TMAP_FLAG_DISTORTION || flags & TMAP_FLAG_DISTORTION_THRUSTER) && use_radius ) {
|
||||
gr_render_effect(n_to_render * 3, vert, radius_list, flags | TMAP_FLAG_TRILIST);
|
||||
} else {
|
||||
gr_render(n_to_render * 3, vert, flags | TMAP_FLAG_TRILIST);
|
||||
@@ -560,7 +560,7 @@ void geometry_batcher::load_buffer(effect_vertex* buffer, int *n_verts)
|
||||
*n_verts = *n_verts + verts_to_render;
|
||||
}
|
||||
|
||||
void geometry_batcher::render_buffer(int flags)
|
||||
void geometry_batcher::render_buffer(int buffer_handle, int flags)
|
||||
{
|
||||
if ( buffer_offset < 0 ) {
|
||||
return;
|
||||
@@ -569,14 +569,95 @@ void geometry_batcher::render_buffer(int flags)
|
||||
if ( !n_to_render ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( buffer_handle < 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
gr_render_stream_buffer(buffer_offset, n_to_render * 3, flags | TMAP_FLAG_TRILIST);
|
||||
gr_render_stream_buffer(buffer_handle, buffer_offset, n_to_render * 3, flags | TMAP_FLAG_TRILIST);
|
||||
|
||||
use_radius = true;
|
||||
n_to_render = 0;
|
||||
buffer_offset = -1;
|
||||
}
|
||||
|
||||
void geometry_shader_batcher::render_buffer(int buffer_handle, int flags)
|
||||
{
|
||||
if ( buffer_offset < 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !vertices.size() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( buffer_handle < 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
gr_render_stream_buffer(buffer_handle, buffer_offset, vertices.size(), flags | TMAP_FLAG_POINTLIST);
|
||||
|
||||
vertices.clear();
|
||||
buffer_offset = -1;
|
||||
}
|
||||
|
||||
void geometry_shader_batcher::load_buffer(particle_pnt* buffer, int *n_verts)
|
||||
{
|
||||
int verts_to_render = vertices.size();
|
||||
int i;
|
||||
|
||||
buffer_offset = *n_verts;
|
||||
|
||||
for ( i = 0; i < verts_to_render; ++i) {
|
||||
buffer[buffer_offset+i] = vertices[i];
|
||||
}
|
||||
|
||||
*n_verts = *n_verts + verts_to_render;
|
||||
}
|
||||
|
||||
void geometry_shader_batcher::draw_bitmap(vertex *position, int orient, float rad, float depth)
|
||||
{
|
||||
float radius = rad;
|
||||
rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad
|
||||
|
||||
vec3d PNT(position->world);
|
||||
vec3d fvec;
|
||||
|
||||
// get the direction from the point to the eye
|
||||
vm_vec_sub(&fvec, &View_position, &PNT);
|
||||
vm_vec_normalize_safe(&fvec);
|
||||
|
||||
// move the center of the sprite based on the depth parameter
|
||||
if ( depth != 0.0f )
|
||||
vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
|
||||
|
||||
particle_pnt new_particle;
|
||||
vec3d up = {0.0f, 1.0f, 0.0f};
|
||||
|
||||
new_particle.position = position->world;
|
||||
new_particle.size = rad;
|
||||
|
||||
int direction = orient % 4;
|
||||
|
||||
if ( direction == 1 ) {
|
||||
up.xyz.x = 0.0f;
|
||||
up.xyz.y = -1.0f;
|
||||
up.xyz.z = 0.0f;
|
||||
} else if ( direction == 2 ) {
|
||||
up.xyz.x = -1.0f;
|
||||
up.xyz.y = 0.0f;
|
||||
up.xyz.z = 0.0f;
|
||||
} else if ( direction == 3 ) {
|
||||
up.xyz.x = 1.0f;
|
||||
up.xyz.y = 0.0f;
|
||||
up.xyz.z = 0.0f;
|
||||
}
|
||||
|
||||
new_particle.up = up;
|
||||
|
||||
vertices.push_back(new_particle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Laser batcher
|
||||
*/
|
||||
@@ -592,67 +673,116 @@ struct batch_item {
|
||||
bool laser;
|
||||
};
|
||||
|
||||
static SCP_vector<batch_item> geometry_map;
|
||||
static SCP_vector<batch_item> distortion_map;
|
||||
struct g_sdr_batch_item {
|
||||
g_sdr_batch_item(): texture(-1), tmap_flags(0), alpha(1.0f), laser(false) {};
|
||||
|
||||
geometry_shader_batcher batch;
|
||||
|
||||
int texture;
|
||||
int tmap_flags;
|
||||
float alpha;
|
||||
|
||||
bool laser;
|
||||
};
|
||||
|
||||
static SCP_map<int, g_sdr_batch_item> geometry_shader_map;
|
||||
static SCP_map<int, batch_item> geometry_map;
|
||||
static SCP_map<int, batch_item> distortion_map;
|
||||
|
||||
// Used for sending verts to the vertex buffer
|
||||
effect_vertex *Batch_buffer = NULL;
|
||||
void *Batch_buffer = NULL;
|
||||
size_t Batch_buffer_size = 0;
|
||||
|
||||
static size_t find_good_batch_item(int texture)
|
||||
{
|
||||
size_t max_size = geometry_map.size();
|
||||
void *Batch_geometry_buffer = NULL;
|
||||
size_t Batch_geometry_buffer_size = 0;
|
||||
|
||||
for (size_t i = 0; i < max_size; i++) {
|
||||
if (geometry_map[i].texture == texture)
|
||||
return i;
|
||||
}
|
||||
|
||||
// don't have an existing match so add a new entry
|
||||
batch_item new_item;
|
||||
|
||||
new_item.texture = texture;
|
||||
|
||||
geometry_map.push_back(new_item);
|
||||
|
||||
return (geometry_map.size() - 1);
|
||||
}
|
||||
|
||||
static size_t find_good_distortion_item(int texture)
|
||||
{
|
||||
size_t max_size = distortion_map.size();
|
||||
|
||||
for (size_t i = 0; i < max_size; i++) {
|
||||
if (distortion_map[i].texture == texture)
|
||||
return i;
|
||||
}
|
||||
|
||||
// don't have an existing match so add a new entry
|
||||
batch_item new_item;
|
||||
|
||||
new_item.texture = texture;
|
||||
|
||||
distortion_map.push_back(new_item);
|
||||
|
||||
return (distortion_map.size() - 1);
|
||||
}
|
||||
// static size_t find_good_batch_item(int texture)
|
||||
// {
|
||||
// size_t max_size = geometry_map.size();
|
||||
//
|
||||
// for (size_t i = 0; i < max_size; i++) {
|
||||
// if (geometry_map[i].texture == texture)
|
||||
// return i;
|
||||
// }
|
||||
//
|
||||
// // don't have an existing match so add a new entry
|
||||
// batch_item new_item;
|
||||
//
|
||||
// new_item.texture = texture;
|
||||
//
|
||||
// geometry_map.push_back(new_item);
|
||||
//
|
||||
// return (geometry_map.size() - 1);
|
||||
// }
|
||||
//
|
||||
// static size_t find_good_g_sdr_batch_item(int texture)
|
||||
// {
|
||||
// size_t max_size = geometry_shader_map.size();
|
||||
//
|
||||
// for (size_t i = 0; i < max_size; i++) {
|
||||
// if (geometry_shader_map[i].texture == texture)
|
||||
// return i;
|
||||
// }
|
||||
//
|
||||
// // don't have an existing match so add a new entry
|
||||
// g_sdr_batch_item new_item;
|
||||
//
|
||||
// new_item.texture = texture;
|
||||
//
|
||||
// geometry_shader_map.push_back(new_item);
|
||||
//
|
||||
// return (geometry_shader_map.size() - 1);
|
||||
// }
|
||||
//
|
||||
// static bool find_good_distortion_item(int texture)
|
||||
// {
|
||||
// SCP_map<int, batch_item>::iterator it = distortion_map.find(texture);
|
||||
//
|
||||
// if ( it == distortion_map.end() ) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// size_t max_size = distortion_map.size();
|
||||
//
|
||||
// for (size_t i = 0; i < max_size; i++) {
|
||||
// if (distortion_map[i].texture == texture)
|
||||
// return i;
|
||||
// }
|
||||
//
|
||||
// // don't have an existing match so add a new entry
|
||||
// batch_item new_item;
|
||||
//
|
||||
// new_item.texture = texture;
|
||||
//
|
||||
// distortion_map.push_back(new_item);
|
||||
//
|
||||
// return (distortion_map.size() - 1);
|
||||
// }
|
||||
|
||||
float batch_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
|
||||
{
|
||||
if (texture < 0) {
|
||||
Int3();
|
||||
return 0.0f;
|
||||
return 1;
|
||||
}
|
||||
|
||||
geometry_batcher *item = NULL;
|
||||
size_t index = find_good_batch_item(texture);
|
||||
batch_item *item = NULL;
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
geometry_map[index].laser = true;
|
||||
item = &geometry_map[index].batch;
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
item->texture = texture;
|
||||
}
|
||||
|
||||
item->add_allocate(1);
|
||||
item->laser = true;
|
||||
|
||||
return item->draw_laser(p0, width1, p1, width2, r, g, b);
|
||||
item->batch.add_allocate(1);
|
||||
|
||||
float num = item->batch.draw_laser(p0, width1, p1, width2, r, g, b);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float rad, float alpha, float depth)
|
||||
@@ -662,23 +792,90 @@ int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float
|
||||
return 1;
|
||||
}
|
||||
|
||||
geometry_batcher *item = NULL;
|
||||
size_t index = find_good_batch_item(texture);
|
||||
if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && ( !Cmdline_softparticles || Use_GLSL <= 2 ) ) {
|
||||
// don't render this as a soft particle if we don't support soft particles
|
||||
tmap_flags &= ~(TMAP_FLAG_SOFT_QUAD);
|
||||
}
|
||||
|
||||
Assertion( (geometry_map[index].laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
if ( Use_GLSL > 2 && Cmdline_softparticles && !Cmdline_no_geo_sdr_effects && Is_Extension_Enabled(OGL_EXT_GEOMETRY_SHADER4) && (tmap_flags & TMAP_FLAG_VERTEX_GEN) ) {
|
||||
geometry_batch_add_bitmap(texture, tmap_flags, pnt, orient, rad, alpha, depth);
|
||||
return 0;
|
||||
} else if ( tmap_flags & TMAP_FLAG_VERTEX_GEN ) {
|
||||
tmap_flags &= ~(TMAP_FLAG_VERTEX_GEN);
|
||||
}
|
||||
|
||||
geometry_map[index].tmap_flags = tmap_flags;
|
||||
geometry_map[index].alpha = alpha;
|
||||
batch_item *item = NULL;
|
||||
|
||||
item = &geometry_map[index].batch;
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
item->add_allocate(1);
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
item->texture = texture;
|
||||
}
|
||||
|
||||
item->draw_bitmap(pnt, orient, rad, depth);
|
||||
Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
item->tmap_flags = tmap_flags;
|
||||
item->alpha = alpha;
|
||||
|
||||
item->batch.add_allocate(1);
|
||||
|
||||
item->batch.draw_bitmap(pnt, orient, rad, depth);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int geometry_batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float rad, float alpha, float depth)
|
||||
{
|
||||
if (texture < 0) {
|
||||
Int3();
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_sdr_batch_item *item = NULL;
|
||||
SCP_map<int, g_sdr_batch_item>::iterator it = geometry_shader_map.find(texture);
|
||||
|
||||
if ( !geometry_shader_map.empty() && it != geometry_shader_map.end() ) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_shader_map[texture];
|
||||
item->texture = texture;
|
||||
}
|
||||
|
||||
Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
item->tmap_flags = tmap_flags;
|
||||
item->alpha = alpha;
|
||||
|
||||
item->batch.draw_bitmap(pnt, orient, rad, depth);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// int geometry_batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha, float depth)
|
||||
// {
|
||||
// if (texture < 0) {
|
||||
// Int3();
|
||||
// return 1;
|
||||
// }
|
||||
//
|
||||
// geometry_shader_batcher *item = NULL;
|
||||
// size_t index = find_good_batch_item(texture);
|
||||
//
|
||||
// Assertion( (geometry_shader_map[index].laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
//
|
||||
// geometry_shader_map[index].tmap_flags = tmap_flags;
|
||||
// geometry_shader_map[index].alpha = alpha;
|
||||
//
|
||||
// item = &geometry_shader_map[index].batch;
|
||||
//
|
||||
// item->draw_bitmap(pnt, rad, angle, depth);
|
||||
//
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha, float depth)
|
||||
{
|
||||
if (texture < 0) {
|
||||
@@ -686,19 +883,170 @@ int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float ang
|
||||
return 1;
|
||||
}
|
||||
|
||||
geometry_batcher *item = NULL;
|
||||
size_t index = find_good_batch_item(texture);
|
||||
if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && ( !Cmdline_softparticles || Use_GLSL <= 2 ) ) {
|
||||
// don't render this as a soft particle if we don't support soft particles
|
||||
tmap_flags &= ~(TMAP_FLAG_SOFT_QUAD);
|
||||
}
|
||||
|
||||
Assertion( (geometry_map[index].laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
batch_item *item = NULL;
|
||||
|
||||
geometry_map[index].tmap_flags = tmap_flags;
|
||||
geometry_map[index].alpha = alpha;
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
item = &geometry_map[index].batch;
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
item->texture = texture;
|
||||
}
|
||||
|
||||
item->add_allocate(1);
|
||||
Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
item->draw_bitmap(pnt, rad, angle, depth);
|
||||
item->tmap_flags = tmap_flags;
|
||||
item->alpha = alpha;
|
||||
|
||||
item->batch.add_allocate(1);
|
||||
|
||||
item->batch.draw_bitmap(pnt, rad, angle, depth);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int batch_add_tri(int texture, int tmap_flags, vertex *verts, float alpha)
|
||||
{
|
||||
if (texture < 0) {
|
||||
Int3();
|
||||
return 1;
|
||||
}
|
||||
|
||||
batch_item *item = NULL;
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
item->texture = texture;
|
||||
}
|
||||
|
||||
Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
item->tmap_flags = tmap_flags;
|
||||
item->alpha = alpha;
|
||||
|
||||
item->batch.add_allocate(0, 1); // just allocating for one triangle
|
||||
|
||||
item->batch.draw_tri(verts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int batch_add_quad(int texture, int tmap_flags, vertex *verts, float alpha)
|
||||
{
|
||||
if (texture < 0) {
|
||||
Int3();
|
||||
return 1;
|
||||
}
|
||||
|
||||
batch_item *item = NULL;
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
item->texture = texture;
|
||||
}
|
||||
|
||||
Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
item->tmap_flags = tmap_flags;
|
||||
item->alpha = alpha;
|
||||
|
||||
item->batch.add_allocate(1);
|
||||
|
||||
item->batch.draw_quad(verts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int batch_add_polygon(int texture, int tmap_flags, vec3d *pos, matrix *orient, float width, float height, float alpha)
|
||||
{
|
||||
//idiot-proof
|
||||
if(width == 0 || height == 0)
|
||||
return 0;
|
||||
|
||||
Assert(pos != NULL);
|
||||
Assert(orient != NULL);
|
||||
|
||||
//Let's begin.
|
||||
|
||||
const int NUM_VERTICES = 4;
|
||||
vec3d p[NUM_VERTICES] = { ZERO_VECTOR };
|
||||
vertex v[NUM_VERTICES];
|
||||
|
||||
p[0].xyz.x = width;
|
||||
p[0].xyz.y = height;
|
||||
|
||||
p[1].xyz.x = -width;
|
||||
p[1].xyz.y = height;
|
||||
|
||||
p[2].xyz.x = -width;
|
||||
p[2].xyz.y = -height;
|
||||
|
||||
p[3].xyz.x = width;
|
||||
p[3].xyz.y = -height;
|
||||
|
||||
for(int i = 0; i < NUM_VERTICES; i++)
|
||||
{
|
||||
vec3d tmp = vmd_zero_vector;
|
||||
|
||||
//Rotate correctly
|
||||
vm_vec_unrotate(&tmp, &p[i], orient);
|
||||
//Move to point in space
|
||||
vm_vec_add2(&tmp, pos);
|
||||
|
||||
//Convert to vertex
|
||||
g3_transfer_vertex(&v[i], &tmp);
|
||||
}
|
||||
|
||||
v[0].texture_position.u = 1.0f;
|
||||
v[0].texture_position.v = 0.0f;
|
||||
|
||||
v[1].texture_position.u = 0.0f;
|
||||
v[1].texture_position.v = 0.0f;
|
||||
|
||||
v[2].texture_position.u = 0.0f;
|
||||
v[2].texture_position.v = 1.0f;
|
||||
|
||||
v[3].texture_position.u = 1.0f;
|
||||
v[3].texture_position.v = 1.0f;
|
||||
|
||||
if (texture < 0) {
|
||||
Int3();
|
||||
return 1;
|
||||
}
|
||||
|
||||
batch_item *item = NULL;
|
||||
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
item->texture = texture;
|
||||
}
|
||||
|
||||
Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
item->tmap_flags = tmap_flags;
|
||||
item->alpha = alpha;
|
||||
|
||||
item->batch.add_allocate(1);
|
||||
|
||||
item->batch.draw_quad(v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -710,93 +1058,155 @@ int batch_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float
|
||||
return 1;
|
||||
}
|
||||
|
||||
geometry_batcher *item = NULL;
|
||||
size_t index = find_good_batch_item(texture);
|
||||
batch_item *item = NULL;
|
||||
|
||||
Assertion( (geometry_map[index].laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
|
||||
|
||||
geometry_map[index].tmap_flags = tmap_flags;
|
||||
geometry_map[index].alpha = intensity;
|
||||
if ( !geometry_map.empty() && it != geometry_map.end() ) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &geometry_map[texture];
|
||||
item->texture = texture;
|
||||
}
|
||||
|
||||
item = &geometry_map[index].batch;
|
||||
Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
item->add_allocate(1);
|
||||
item->tmap_flags = tmap_flags;
|
||||
item->alpha = intensity;
|
||||
|
||||
item->draw_beam(start, end, width, intensity);
|
||||
item->batch.add_allocate(1);
|
||||
|
||||
item->batch.draw_beam(start, end, width, intensity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void batch_render_lasers(bool stream_buffer)
|
||||
void batch_render_lasers(int buffer_handle)
|
||||
{
|
||||
for (SCP_vector<batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
|
||||
if ( !bi->laser )
|
||||
if ( !bi->second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->batch.need_to_render() )
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->texture >= 0 );
|
||||
gr_set_bitmap(bi->texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f);
|
||||
if ( stream_buffer ) {
|
||||
bi->batch.render_buffer(TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);
|
||||
Assert( bi->second.texture >= 0 );
|
||||
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f);
|
||||
if ( buffer_handle >= 0 ) {
|
||||
bi->second.batch.render_buffer(buffer_handle, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);
|
||||
} else {
|
||||
bi->batch.render(TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);
|
||||
bi->second.batch.render(TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void batch_load_buffer_lasers(effect_vertex* buffer, int *n_verts)
|
||||
{
|
||||
for (SCP_vector<batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
|
||||
if ( !bi->laser )
|
||||
if ( !bi->second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->batch.need_to_render() )
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->texture >= 0 );
|
||||
bi->batch.load_buffer(buffer, n_verts);
|
||||
Assert( bi->second.texture >= 0 );
|
||||
bi->second.batch.load_buffer(buffer, n_verts);
|
||||
}
|
||||
}
|
||||
|
||||
void batch_render_geometry_map_bitmaps(bool stream_buffer)
|
||||
void batch_render_geometry_map_bitmaps(int buffer_handle)
|
||||
{
|
||||
for (SCP_vector<batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
|
||||
if ( bi->laser )
|
||||
if ( bi->second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->batch.need_to_render() )
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->texture >= 0 );
|
||||
gr_set_bitmap(bi->texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi->alpha);
|
||||
if ( stream_buffer ) {
|
||||
bi->batch.render_buffer(bi->tmap_flags);
|
||||
Assert( bi->second.texture >= 0 );
|
||||
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
|
||||
if ( buffer_handle >= 0 ) {
|
||||
bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
|
||||
} else {
|
||||
bi->batch.render( bi->tmap_flags);
|
||||
bi->second.batch.render( bi->second.tmap_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void batch_render_geometry_shader_map_bitmaps(int buffer_handle)
|
||||
{
|
||||
for (SCP_map<int, g_sdr_batch_item>::iterator bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
|
||||
|
||||
if ( bi->second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->second.texture >= 0 );
|
||||
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
|
||||
bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
|
||||
}
|
||||
}
|
||||
|
||||
void batch_load_buffer_geometry_map_bitmaps(effect_vertex* buffer, int *n_verts)
|
||||
{
|
||||
for (SCP_vector<batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
|
||||
if ( bi->laser )
|
||||
if ( bi->second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->batch.need_to_render() )
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->texture >= 0 );
|
||||
bi->batch.load_buffer(buffer, n_verts);
|
||||
Assert( bi->second.texture >= 0 );
|
||||
bi->second.batch.load_buffer(buffer, n_verts);
|
||||
}
|
||||
}
|
||||
|
||||
void batch_load_buffer_geometry_shader_map_bitmaps(particle_pnt* buffer, int *n_verts)
|
||||
{
|
||||
for (SCP_map<int, g_sdr_batch_item>::iterator bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
|
||||
|
||||
if ( bi->second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->second.texture >= 0 );
|
||||
bi->second.batch.load_buffer(buffer, n_verts);
|
||||
}
|
||||
}
|
||||
|
||||
void geometry_batch_render(int stream_buffer)
|
||||
{
|
||||
if ( stream_buffer < 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
int n_to_render = geometry_batch_get_size();
|
||||
int n_verts = 0;
|
||||
|
||||
if ( Batch_geometry_buffer_size < (n_to_render * sizeof(particle_pnt)) ) {
|
||||
if ( Batch_geometry_buffer != NULL ) {
|
||||
vm_free(Batch_geometry_buffer);
|
||||
}
|
||||
|
||||
Batch_geometry_buffer_size = n_to_render * sizeof(particle_pnt);
|
||||
Batch_geometry_buffer = vm_malloc(Batch_geometry_buffer_size);
|
||||
}
|
||||
|
||||
batch_load_buffer_geometry_shader_map_bitmaps((particle_pnt*)Batch_geometry_buffer, &n_verts);
|
||||
|
||||
gr_update_buffer_object(stream_buffer, Batch_geometry_buffer_size, Batch_geometry_buffer);
|
||||
|
||||
batch_render_geometry_shader_map_bitmaps(stream_buffer);
|
||||
}
|
||||
|
||||
void batch_render_all(int stream_buffer)
|
||||
{
|
||||
if ( stream_buffer >= 0 ) {
|
||||
@@ -810,27 +1220,26 @@ void batch_render_all(int stream_buffer)
|
||||
}
|
||||
|
||||
Batch_buffer_size = n_to_render * sizeof(effect_vertex);
|
||||
Batch_buffer = (effect_vertex*)vm_malloc(Batch_buffer_size);
|
||||
Batch_buffer = vm_malloc(Batch_buffer_size);
|
||||
}
|
||||
|
||||
gr_render_stream_buffer_start(stream_buffer);
|
||||
|
||||
batch_load_buffer_lasers(Batch_buffer, &n_verts);
|
||||
batch_load_buffer_geometry_map_bitmaps(Batch_buffer, &n_verts);
|
||||
batch_load_buffer_distortion_map_bitmaps(Batch_buffer, &n_verts);
|
||||
gr_update_stream_buffer(stream_buffer, Batch_buffer, Batch_buffer_size);
|
||||
batch_load_buffer_lasers((effect_vertex*)Batch_buffer, &n_verts);
|
||||
batch_load_buffer_geometry_map_bitmaps((effect_vertex*)Batch_buffer, &n_verts);
|
||||
batch_load_buffer_distortion_map_bitmaps((effect_vertex*)Batch_buffer, &n_verts);
|
||||
gr_update_buffer_object(stream_buffer, Batch_buffer_size, Batch_buffer);
|
||||
|
||||
Assert(n_verts <= n_to_render);
|
||||
|
||||
batch_render_lasers(true);
|
||||
batch_render_geometry_map_bitmaps(true);
|
||||
batch_render_distortion_map_bitmaps(true);
|
||||
gr_render_stream_buffer_end();
|
||||
batch_render_lasers(stream_buffer);
|
||||
batch_render_geometry_map_bitmaps(stream_buffer);
|
||||
//batch_render_distortion_map_bitmaps(true);
|
||||
} else {
|
||||
batch_render_lasers();
|
||||
batch_render_geometry_map_bitmaps();
|
||||
batch_render_distortion_map_bitmaps();
|
||||
//batch_render_distortion_map_bitmaps();
|
||||
}
|
||||
|
||||
gr_clear_states();
|
||||
}
|
||||
|
||||
void batch_reset()
|
||||
@@ -856,19 +1265,30 @@ int distortion_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, floa
|
||||
return 1;
|
||||
}
|
||||
|
||||
geometry_batcher *item = NULL;
|
||||
size_t index = find_good_distortion_item(texture);
|
||||
if ( Use_GLSL < 2 || !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) ) {
|
||||
// don't render distortions if we can't support them.
|
||||
return 0;
|
||||
}
|
||||
|
||||
Assertion( (distortion_map[index].laser == false), "Distortion particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
batch_item *item = NULL;
|
||||
|
||||
distortion_map[index].tmap_flags = tmap_flags;
|
||||
distortion_map[index].alpha = alpha;
|
||||
SCP_map<int, batch_item>::iterator it = distortion_map.find(texture);
|
||||
|
||||
item = &distortion_map[index].batch;
|
||||
if ( !distortion_map.empty() && it != distortion_map.end() ) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &distortion_map[texture];
|
||||
item->texture = texture;
|
||||
}
|
||||
|
||||
item->add_allocate(1);
|
||||
Assertion( (item->laser == false), "Distortion particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
item->draw_bitmap(pnt, rad, angle, depth);
|
||||
item->tmap_flags = tmap_flags;
|
||||
item->alpha = alpha;
|
||||
|
||||
item->batch.add_allocate(1);
|
||||
|
||||
item->batch.draw_bitmap(pnt, rad, angle, depth);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -880,74 +1300,97 @@ int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, f
|
||||
return 1;
|
||||
}
|
||||
|
||||
geometry_batcher *item = NULL;
|
||||
size_t index = find_good_distortion_item(texture);
|
||||
if ( Use_GLSL < 2 || !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) ) {
|
||||
// don't render distortions if we can't support them.
|
||||
return 0;
|
||||
}
|
||||
|
||||
Assertion( (distortion_map[index].laser == false), "Distortion particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
batch_item *item = NULL;
|
||||
|
||||
distortion_map[index].tmap_flags = tmap_flags;
|
||||
distortion_map[index].alpha = intensity;
|
||||
SCP_map<int, batch_item>::iterator it = distortion_map.find(texture);
|
||||
|
||||
item = &distortion_map[index].batch;
|
||||
if ( !distortion_map.empty() && it != distortion_map.end() ) {
|
||||
item = &it->second;
|
||||
} else {
|
||||
item = &distortion_map[texture];
|
||||
item->texture = texture;
|
||||
}
|
||||
|
||||
item->add_allocate(1);
|
||||
Assertion( (item->laser == false), "Distortion particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
item->draw_beam(start,end,width,intensity,offset);
|
||||
item->tmap_flags = tmap_flags;
|
||||
item->alpha = intensity;
|
||||
|
||||
item->batch.add_allocate(1);
|
||||
|
||||
item->batch.draw_beam(start,end,width,intensity,offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void batch_render_distortion_map_bitmaps(bool stream_buffer)
|
||||
void batch_render_distortion_map_bitmaps(int buffer_handle)
|
||||
{
|
||||
for (SCP_vector<batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
|
||||
for (SCP_map<int,batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
|
||||
|
||||
if ( bi->laser )
|
||||
if ( bi->second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->batch.need_to_render() )
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->texture >= 0 );
|
||||
gr_set_bitmap(bi->texture, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, bi->alpha);
|
||||
Assert( bi->second.texture >= 0 );
|
||||
gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
|
||||
|
||||
if ( stream_buffer ) {
|
||||
bi->batch.render_buffer(bi->tmap_flags);
|
||||
if ( buffer_handle >= 0 ) {
|
||||
bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
|
||||
} else {
|
||||
bi->batch.render( bi->tmap_flags);
|
||||
bi->second.batch.render( bi->second.tmap_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void batch_load_buffer_distortion_map_bitmaps(effect_vertex* buffer, int *n_verts)
|
||||
{
|
||||
for (SCP_vector<batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
|
||||
for (SCP_map<int, batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
|
||||
|
||||
if ( bi->laser )
|
||||
if ( bi->second.laser )
|
||||
continue;
|
||||
|
||||
if ( !bi->batch.need_to_render() )
|
||||
if ( !bi->second.batch.need_to_render() )
|
||||
continue;
|
||||
|
||||
Assert( bi->texture >= 0 );
|
||||
bi->batch.load_buffer(buffer, n_verts);
|
||||
Assert( bi->second.texture >= 0 );
|
||||
bi->second.batch.load_buffer(buffer, n_verts);
|
||||
}
|
||||
}
|
||||
|
||||
int batch_get_size()
|
||||
{
|
||||
int n_to_render = 0;
|
||||
SCP_vector<batch_item>::iterator bi;
|
||||
SCP_map<int, batch_item>::iterator bi;
|
||||
|
||||
for (bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
n_to_render += bi->batch.need_to_render();
|
||||
n_to_render += bi->second.batch.need_to_render();
|
||||
}
|
||||
|
||||
for (bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
|
||||
if ( bi->laser )
|
||||
if ( bi->second.laser )
|
||||
continue;
|
||||
|
||||
n_to_render += bi->batch.need_to_render();
|
||||
n_to_render += bi->second.batch.need_to_render();
|
||||
}
|
||||
|
||||
return n_to_render * 3;
|
||||
}
|
||||
|
||||
int geometry_batch_get_size()
|
||||
{
|
||||
int n_to_render = 0;
|
||||
SCP_map<int, g_sdr_batch_item>::iterator bi;
|
||||
|
||||
for (bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
|
||||
n_to_render += bi->second.batch.need_to_render();
|
||||
}
|
||||
|
||||
return n_to_render;
|
||||
}
|
||||
+31
-4
@@ -66,7 +66,7 @@ public:
|
||||
|
||||
void load_buffer(effect_vertex* buffer, int *n_verts);
|
||||
|
||||
void render_buffer(int flags);
|
||||
void render_buffer(int buffer_handle, int flags);
|
||||
|
||||
// determine if we even need to try and render this (helpful for particle system)
|
||||
int need_to_render() { return n_to_render; }
|
||||
@@ -74,24 +74,51 @@ public:
|
||||
void operator =(int){}
|
||||
};
|
||||
|
||||
class geometry_shader_batcher
|
||||
{
|
||||
SCP_vector<particle_pnt> vertices;
|
||||
|
||||
int buffer_offset;
|
||||
public:
|
||||
// draw a bitmap into the geometry batcher
|
||||
void draw_bitmap(vertex *position, int orient, float rad, float depth = 0);
|
||||
|
||||
// draw a rotated bitmap
|
||||
// void draw_bitmap(vertex *position, float rad, float angle, float depth);
|
||||
|
||||
void load_buffer(particle_pnt* buffer, int *n_verts);
|
||||
|
||||
void render_buffer(int buffer_handle, int flags);
|
||||
|
||||
int need_to_render() { return vertices.size(); };
|
||||
};
|
||||
|
||||
|
||||
float batch_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float width2, int r = 255, int g = 255, int b = 255);
|
||||
int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float rad, float alpha = 1.0f, float depth = 0.0f);
|
||||
int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha = 1.0f, float depth = 0.0f);
|
||||
int batch_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity = 1.0f);
|
||||
int batch_add_polygon(int texture, int tmap_flags, vec3d *pos, matrix *orient, float width, float height, float alpha = 1.0f);
|
||||
int batch_add_tri(int texture, int tmap_flags, vertex *verts, float alpha = 1.0f);
|
||||
int batch_add_quad(int texture, int tmap_flags, vertex *verts, float alpha = 1.0f);
|
||||
int distortion_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha = 1.0f, float depth = 0.0f);
|
||||
int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity = 1.0f, float offset = 0.0f);
|
||||
void batch_render_all(int stream_buffer = -1);
|
||||
void batch_render_geometry_map_bitmaps(bool stream_buffer = false);
|
||||
void batch_render_geometry_map_bitmaps(int buffer_handle = -1);
|
||||
void batch_load_buffer_geometry_map_bitmaps(effect_vertex* buffer, int *n_verts);
|
||||
void batch_render_lasers(bool stream_buffer = false);
|
||||
void batch_render_lasers(int buffer_handle = -1);
|
||||
void batch_load_buffer_lasers(effect_vertex* buffer, int *n_verts);
|
||||
void batch_reset();
|
||||
void batch_render_distortion_map_bitmaps(bool stream_buffer = false);
|
||||
void batch_render_distortion_map_bitmaps(int buffer_handle = -1);
|
||||
void batch_load_buffer_distortion_map_bitmaps(effect_vertex* buffer, int *n_verts);
|
||||
|
||||
int batch_get_size();
|
||||
void batch_render_close();
|
||||
|
||||
int geometry_batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float rad, float alpha, float depth);
|
||||
void batch_load_buffer_geometry_shader_map_bitmaps(particle_pnt* buffer, int *n_verts);
|
||||
void batch_render_geometry_shader_map_bitmaps();
|
||||
void geometry_batch_render(int stream_buffer);
|
||||
int geometry_batch_get_size();
|
||||
|
||||
#endif
|
||||
@@ -68,7 +68,8 @@ typedef enum gr_alpha_blend {
|
||||
ALPHA_BLEND_ADDITIVE, // 1*SrcPixel + 1*DestPixel
|
||||
ALPHA_BLEND_ALPHA_ADDITIVE, // Alpha*SrcPixel + 1*DestPixel
|
||||
ALPHA_BLEND_ALPHA_BLEND_ALPHA, // Alpha*SrcPixel + (1-Alpha)*DestPixel
|
||||
ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR // Alpha*SrcPixel + (1-SrcPixel)*DestPixel
|
||||
ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR, // Alpha*SrcPixel + (1-SrcPixel)*DestPixel
|
||||
ALPHA_BLEND_PREMULTIPLIED // 1*SrcPixel + (1-Alpha)*DestPixel
|
||||
} gr_alpha_blend;
|
||||
|
||||
typedef enum gr_zbuffer_type {
|
||||
|
||||
+36
-14
@@ -1248,24 +1248,29 @@ void gr_opengl_dump_frame()
|
||||
void gr_opengl_set_fill_mode(int mode)
|
||||
{
|
||||
if (mode == GR_FILL_MODE_SOLID) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
GL_state.SetPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == GR_FILL_MODE_WIRE) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
GL_state.SetPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
return;
|
||||
}
|
||||
|
||||
// default setting
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
GL_state.SetPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
void gr_opengl_zbias(int bias)
|
||||
{
|
||||
if (bias) {
|
||||
GL_state.PolygonOffsetFill(GL_TRUE);
|
||||
glPolygonOffset(0.0, -i2fl(bias));
|
||||
if(bias < 0) {
|
||||
GL_state.SetPolygonOffset(1.0, -i2fl(bias));
|
||||
}
|
||||
else {
|
||||
GL_state.SetPolygonOffset(0.0, -i2fl(bias));
|
||||
}
|
||||
} else {
|
||||
GL_state.PolygonOffsetFill(GL_FALSE);
|
||||
}
|
||||
@@ -1859,12 +1864,13 @@ void opengl_setup_function_pointers()
|
||||
gr_screen.gf_destroy_buffer = gr_opengl_destroy_buffer;
|
||||
gr_screen.gf_render_buffer = gr_opengl_render_buffer;
|
||||
gr_screen.gf_set_buffer = gr_opengl_set_buffer;
|
||||
gr_screen.gf_update_buffer_object = gr_opengl_update_buffer_object;
|
||||
|
||||
gr_screen.gf_create_stream_buffer = gr_opengl_create_stream_buffer;
|
||||
gr_screen.gf_update_stream_buffer = gr_opengl_update_stream_buffer;
|
||||
gr_screen.gf_update_transform_buffer = gr_opengl_update_transform_buffer;
|
||||
gr_screen.gf_set_transform_buffer_offset = gr_opengl_set_transform_buffer_offset;
|
||||
|
||||
gr_screen.gf_create_stream_buffer = gr_opengl_create_stream_buffer_object;
|
||||
gr_screen.gf_render_stream_buffer = gr_opengl_render_stream_buffer;
|
||||
gr_screen.gf_render_stream_buffer_start = gr_opengl_render_stream_buffer_start;
|
||||
gr_screen.gf_render_stream_buffer_end = gr_opengl_render_stream_buffer_end;
|
||||
|
||||
gr_screen.gf_start_instance_matrix = gr_opengl_start_instance_matrix;
|
||||
gr_screen.gf_end_instance_matrix = gr_opengl_end_instance_matrix;
|
||||
@@ -1886,11 +1892,17 @@ void opengl_setup_function_pointers()
|
||||
|
||||
gr_screen.gf_scene_texture_begin = gr_opengl_scene_texture_begin;
|
||||
gr_screen.gf_scene_texture_end = gr_opengl_scene_texture_end;
|
||||
gr_screen.gf_copy_effect_texture = gr_opengl_copy_effect_texture;
|
||||
|
||||
gr_screen.gf_deferred_lighting_begin = gr_opengl_deferred_lighting_begin;
|
||||
gr_screen.gf_deferred_lighting_end = gr_opengl_deferred_lighting_end;
|
||||
gr_screen.gf_deferred_lighting_finish = gr_opengl_deferred_lighting_finish;
|
||||
|
||||
gr_screen.gf_start_clip_plane = gr_opengl_start_clip_plane;
|
||||
gr_screen.gf_end_clip_plane = gr_opengl_end_clip_plane;
|
||||
|
||||
gr_screen.gf_lighting = gr_opengl_set_lighting;
|
||||
gr_screen.gf_set_light_factor = gr_opengl_set_light_factor;
|
||||
|
||||
gr_screen.gf_set_proj_matrix = gr_opengl_set_projection_matrix;
|
||||
gr_screen.gf_end_proj_matrix = gr_opengl_end_projection_matrix;
|
||||
@@ -1901,6 +1913,7 @@ void opengl_setup_function_pointers()
|
||||
gr_screen.gf_push_scale_matrix = gr_opengl_push_scale_matrix;
|
||||
gr_screen.gf_pop_scale_matrix = gr_opengl_pop_scale_matrix;
|
||||
gr_screen.gf_center_alpha = gr_opengl_center_alpha;
|
||||
gr_screen.gf_set_thrust_scale = gr_opengl_set_thrust_scale;
|
||||
|
||||
gr_screen.gf_setup_background_fog = gr_opengl_setup_background_fog;
|
||||
|
||||
@@ -1915,14 +1928,19 @@ void opengl_setup_function_pointers()
|
||||
gr_screen.gf_line_htl = gr_opengl_line_htl;
|
||||
gr_screen.gf_sphere_htl = gr_opengl_sphere_htl;
|
||||
|
||||
gr_screen.gf_set_animated_effect = gr_opengl_shader_set_animated_effect;
|
||||
|
||||
gr_screen.gf_maybe_create_shader = gr_opengl_maybe_create_shader;
|
||||
|
||||
gr_screen.gf_flush_data_states = gr_opengl_flush_data_states;
|
||||
|
||||
gr_screen.gf_set_team_color = gr_opengl_set_team_color;
|
||||
gr_screen.gf_disable_team_color = gr_opengl_disable_team_color;
|
||||
gr_screen.gf_shadow_map_start = gr_opengl_shadow_map_start;
|
||||
gr_screen.gf_shadow_map_end = gr_opengl_shadow_map_end;
|
||||
|
||||
gr_screen.gf_update_texture = gr_opengl_update_texture;
|
||||
gr_screen.gf_get_bitmap_from_texture = gr_opengl_get_bitmap_from_texture;
|
||||
|
||||
gr_screen.gf_clear_states = gr_opengl_clear_states;
|
||||
|
||||
gr_screen.gf_set_team_color = gr_opengl_set_team_color;
|
||||
|
||||
// NOTE: All function pointers here should have a Cmdline_nohtl check at the top
|
||||
// if they shouldn't be run in non-HTL mode, Don't keep separate entries.
|
||||
// *****************************************************************************
|
||||
@@ -1984,13 +2002,16 @@ bool gr_opengl_init()
|
||||
GL_state.init();
|
||||
|
||||
GLint max_texture_units = GL_supported_texture_units;
|
||||
GLint max_texture_coords = GL_supported_texture_units;
|
||||
|
||||
if (Use_GLSL) {
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &max_texture_units);
|
||||
}
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);
|
||||
|
||||
GL_state.Texture.init(max_texture_units);
|
||||
GL_state.Array.init(max_texture_units);
|
||||
GL_state.Array.init(max_texture_coords);
|
||||
|
||||
opengl_set_texture_target();
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
@@ -2050,6 +2071,7 @@ bool gr_opengl_init()
|
||||
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &GL_max_elements_indices);
|
||||
|
||||
mprintf(( " Max texture units: %i (%i)\n", GL_supported_texture_units, max_texture_units ));
|
||||
mprintf(( " Max client texture states: %i (%i)\n", GL_supported_texture_units, max_texture_coords ));
|
||||
mprintf(( " Max elements vertices: %i\n", GL_max_elements_vertices ));
|
||||
mprintf(( " Max elements indices: %i\n", GL_max_elements_indices ));
|
||||
mprintf(( " Max texture size: %ix%i\n", GL_max_texture_width, GL_max_texture_height ));
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "pcxutils/pcxutils.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "graphics/gropenglstate.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "anim/animplay.h"
|
||||
#include "anim/packunpack.h"
|
||||
@@ -554,7 +555,7 @@ void gr_opengl_bm_save_render_target(int n)
|
||||
bitmap_entry *be = &bm_bitmaps[n];
|
||||
bitmap *bmp = &be->bm;
|
||||
|
||||
int rc = opengl_export_image(n, bmp->w, bmp->h, (bmp->true_bpp == 32), be->num_mipmaps, (ubyte*)bmp->data);
|
||||
int rc = opengl_export_render_target( n, bmp->w, bmp->h, (bmp->true_bpp == 32), be->num_mipmaps, (ubyte*)bmp->data );
|
||||
|
||||
if (rc != be->mem_taken) {
|
||||
Int3();
|
||||
|
||||
+828
-240
File diff suppressed because it is too large.
Load diff
@@ -12,6 +12,8 @@
|
||||
#define GR_OPENGLDRAW_H
|
||||
|
||||
#include "graphics/gropenglstate.h"
|
||||
#include "graphics/shadows.h"
|
||||
#include "graphics/2d.h"
|
||||
|
||||
void gr_opengl_aabitmap_ex(int x, int y, int w, int h, int sx, int sy, int resize_mode, bool mirror);
|
||||
void gr_opengl_aabitmap(int x, int y, int resize_mode, bool mirror);
|
||||
@@ -43,13 +45,53 @@ void opengl_reset_spec_mapping();
|
||||
|
||||
void gr_opengl_line_htl(vec3d *start, vec3d *end);
|
||||
void gr_opengl_sphere_htl(float rad);
|
||||
void gr_opengl_deferred_light_sphere_init(int rings, int segments);
|
||||
void gr_opengl_draw_deferred_light_sphere(vec3d *position, float rad, bool clearStencil);
|
||||
void gr_opengl_deferred_light_cylinder_init(int segments);
|
||||
void gr_opengl_draw_deferred_light_cylinder(vec3d *position,matrix *orient, float rad, float length, bool clearStencil);
|
||||
|
||||
void gr_opengl_draw_line_list(colored_vector *lines, int num);
|
||||
|
||||
void gr_opengl_shadow_map_start(matrix4 *shadow_view_matrix, matrix *light_orient);
|
||||
void gr_opengl_shadow_map_end();
|
||||
|
||||
void opengl_setup_scene_textures();
|
||||
void opengl_scene_texture_shutdown();
|
||||
void gr_opengl_scene_texture_begin();
|
||||
void gr_opengl_scene_texture_end();
|
||||
void gr_opengl_copy_effect_texture();
|
||||
|
||||
void opengl_clear_deferred_buffers();
|
||||
void gr_opengl_deferred_lighting_begin();
|
||||
void gr_opengl_deferred_lighting_end();
|
||||
void gr_opengl_deferred_lighting_finish();
|
||||
|
||||
void opengl_bind_vertex_layout(vertex_layout &layout);
|
||||
|
||||
inline void opengl_draw_textured_quad_instanced(
|
||||
GLfloat x1, GLfloat y1, GLfloat u1, GLfloat v1,
|
||||
GLfloat x2, GLfloat y2, GLfloat u2, GLfloat v2,
|
||||
int count )
|
||||
{
|
||||
GLfloat glVertices[4][4] = {
|
||||
{ x1, y1, u1, v1 },
|
||||
{ x1, y2, u1, v2 },
|
||||
{ x2, y1, u2, v1 },
|
||||
{ x2, y2, u2, v2 }
|
||||
};
|
||||
|
||||
GL_state.Array.BindArrayBuffer(0);
|
||||
|
||||
vertex_layout vert_def;
|
||||
|
||||
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
|
||||
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
|
||||
|
||||
opengl_bind_vertex_layout(vert_def);
|
||||
|
||||
//glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
vglDrawArraysInstancedARB(GL_TRIANGLE_STRIP, 0, 4, count);
|
||||
}
|
||||
|
||||
inline void opengl_draw_textured_quad(
|
||||
GLfloat x1, GLfloat y1, GLfloat u1, GLfloat v1,
|
||||
@@ -64,17 +106,14 @@ inline void opengl_draw_textured_quad(
|
||||
|
||||
GL_state.Array.BindArrayBuffer(0);
|
||||
|
||||
GL_state.Array.EnableClientVertex();
|
||||
GL_state.Array.VertexPointer(2, GL_FLOAT, sizeof(glVertices[0]), glVertices);
|
||||
vertex_layout vert_def;
|
||||
|
||||
GL_state.Array.SetActiveClientUnit(0);
|
||||
GL_state.Array.EnableClientTexture();
|
||||
GL_state.Array.TexPointer(2, GL_FLOAT, sizeof(glVertices[0]), &(glVertices[0][2]));
|
||||
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
|
||||
vert_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
|
||||
|
||||
opengl_bind_vertex_layout(vert_def);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
GL_state.Array.DisableClientVertex();
|
||||
GL_state.Array.DisableClientTexture();
|
||||
}
|
||||
|
||||
inline void opengl_draw_coloured_quad(
|
||||
@@ -88,12 +127,13 @@ inline void opengl_draw_coloured_quad(
|
||||
x2, y2
|
||||
};
|
||||
|
||||
GL_state.Array.EnableClientVertex();
|
||||
GL_state.Array.VertexPointer(2, GL_INT, 0, glVertices);
|
||||
vertex_layout vert_def;
|
||||
|
||||
vert_def.add_vertex_component(vertex_format_data::SCREEN_POS, 0, glVertices);
|
||||
|
||||
opengl_bind_vertex_layout(vert_def);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
GL_state.Array.DisableClientVertex();
|
||||
}
|
||||
|
||||
inline void opengl_draw_coloured_quad(
|
||||
@@ -107,12 +147,13 @@ inline void opengl_draw_coloured_quad(
|
||||
x2, y2
|
||||
};
|
||||
|
||||
GL_state.Array.EnableClientVertex();
|
||||
GL_state.Array.VertexPointer(2, GL_FLOAT, 0, glVertices);
|
||||
vertex_layout vert_def;
|
||||
|
||||
vert_def.add_vertex_component(vertex_format_data::POSITION2, 0, glVertices);
|
||||
|
||||
opengl_bind_vertex_layout(vert_def);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
GL_state.Array.DisableClientVertex();
|
||||
}
|
||||
|
||||
extern int Scene_texture_initialized;
|
||||
@@ -127,6 +168,8 @@ extern int Scene_texture_height;
|
||||
extern float Scene_texture_u_scale;
|
||||
extern float Scene_texture_v_scale;
|
||||
|
||||
extern bool Deferred_lighting;
|
||||
|
||||
extern bool Use_Shaders_for_effect_rendering;
|
||||
|
||||
#endif // !GR_OPENGLDRAW_H
|
||||
@@ -131,10 +131,10 @@ ogl_extension GL_Extensions[NUM_OGL_EXTENSIONS] =
|
||||
{ false, false, 1, { "GL_ARB_shading_language_100" }, 0, { NULL } },
|
||||
|
||||
// shader objects and program object management
|
||||
{ false, false, 1, { "GL_ARB_shader_objects" }, 18, { "glDeleteObjectARB", "glCreateShaderObjectARB", "glShaderSourceARB",
|
||||
{ false, false, 1, { "GL_ARB_shader_objects" }, 19, { "glDeleteObjectARB", "glCreateShaderObjectARB", "glShaderSourceARB",
|
||||
"glCompileShaderARB", "glGetObjectParameterivARB", "glGetInfoLogARB", "glCreateProgramObjectARB",
|
||||
"glAttachObjectARB", "glLinkProgramARB", "glUseProgramObjectARB", "glValidateProgramARB", "glGetUniformLocationARB",
|
||||
"glGetUniformivARB", "glUniform1fARB", "glUniform2fARB", "glUniform3fARB", "glUniform1iARB", "glUniformMatrix4fvARB" } },
|
||||
"glGetUniformivARB", "glUniform1fARB", "glUniform2fARB", "glUniform3fARB", "glUniform4fARB", "glUniform1iARB", "glUniformMatrix4fvARB" } },
|
||||
|
||||
// programmable vertex level processing
|
||||
// some of functions are provided by GL_ARB_vertex_program
|
||||
@@ -150,7 +150,25 @@ ogl_extension GL_Extensions[NUM_OGL_EXTENSIONS] =
|
||||
{ false, false, 1, { "GL_ARB_texture_float" }, 0, { NULL } },
|
||||
|
||||
{ false, false, 1, { "GL_ARB_draw_elements_base_vertex" }, 4, { "glDrawElementsBaseVertex", "glDrawRangeElementsBaseVertex",
|
||||
"glDrawElementsInstancedBaseVertex", "glMultiDrawElementsBaseVertex" } }
|
||||
"glDrawElementsInstancedBaseVertex", "glMultiDrawElementsBaseVertex" } },
|
||||
|
||||
{ false, false, 1, {"GL_EXT_framebuffer_blit" }, 1, { "glBlitFramebufferEXT" } },
|
||||
|
||||
// geometry shaders
|
||||
{ false, false, 1, { "GL_EXT_geometry_shader4" }, 2, { "glProgramParameteriEXT", "glFramebufferTextureEXT" } },
|
||||
|
||||
// array textures
|
||||
{ false, false, 1, { "GL_EXT_texture_array" }, 1, { "glTexImage3D" } },
|
||||
|
||||
{ false, false, 1, { "GL_ARB_uniform_buffer_object" }, 7, { "glGetUniformIndices", "glGetActiveUniformsiv", "glGetActiveUniformName",
|
||||
"glGetUniformBlockIndex", "glGetActiveUniformBlockiv", "glGetActiveUniformBlockName", "glUniformBlockBinding" } },
|
||||
|
||||
{ false, false, 1, { "GL_EXT_transform_feedback" }, 7, { "glBeginTransformFeedbackEXT", "glEndTransformFeedbackEXT", "glBindBufferRangeEXT",
|
||||
"glBindBufferOffsetEXT", "glBindBufferBaseEXT", "glTransformFeedbackVaryingsEXT", "glGetTransformFeedbackVaryingEXT" } },
|
||||
|
||||
{ false, false, 1, { "GL_ARB_draw_instanced" }, 2, { "glDrawArraysInstancedARB", "glDrawElementsInstancedARB" } },
|
||||
|
||||
{ false, false, 1, { "GL_ARB_texture_buffer_object" }, 1, { "glTexBufferARB" } }
|
||||
};
|
||||
|
||||
// ogl_funcion is:
|
||||
@@ -226,7 +244,28 @@ ogl_function GL_Functions[NUM_OGL_FUNCTIONS] =
|
||||
{ "glDrawElementsBaseVertex", 0 },
|
||||
{ "glDrawRangeElementsBaseVertex", 0 },
|
||||
{ "glDrawElementsInstancedBaseVertex", 0 },
|
||||
{ "glMultiDrawElementsBaseVertex", 0 }
|
||||
{ "glMultiDrawElementsBaseVertex", 0 },
|
||||
{ "glBlitFramebufferEXT", 0},
|
||||
{ "glProgramParameteriEXT", 0 },
|
||||
{ "glTexImage3D", 0 },
|
||||
{ "glFramebufferTextureEXT", 0 },
|
||||
{ "glGetUniformIndices", 0 },
|
||||
{ "glGetActiveUniformsiv", 0 },
|
||||
{ "glGetActiveUniformName", 0 },
|
||||
{ "glGetUniformBlockIndex", 0 },
|
||||
{ "glGetActiveUniformBlockiv", 0 },
|
||||
{ "glGetActiveUniformBlockName", 0 },
|
||||
{ "glUniformBlockBinding", 0 },
|
||||
{ "glBeginTransformFeedbackEXT", 0 },
|
||||
{ "glEndTransformFeedbackEXT", 0 },
|
||||
{ "glBindBufferRangeEXT", 0 },
|
||||
{ "glBindBufferOffsetEXT", 0 },
|
||||
{ "glBindBufferBaseEXT", 0 },
|
||||
{ "glTransformFeedbackVaryingsEXT", 0 },
|
||||
{ "glGetTransformFeedbackVaryingEXT", 0 },
|
||||
{ "glDrawArraysInstancedARB", 0 },
|
||||
{ "glDrawElementsInstancedARB", 0 },
|
||||
{ "glTexBufferARB", 0 }
|
||||
};
|
||||
|
||||
// special extensions (only special functions are supported at the moment)
|
||||
@@ -394,6 +433,14 @@ void opengl_extensions_init()
|
||||
if ( !(Is_Extension_Enabled(OGL_ARB_TEXTURE_CUBE_MAP) && Is_Extension_Enabled(OGL_ARB_TEXTURE_ENV_COMBINE)) ) {
|
||||
Cmdline_env = 0;
|
||||
}
|
||||
|
||||
if ( !(Is_Extension_Enabled(OGL_EXT_GEOMETRY_SHADER4) && Is_Extension_Enabled(OGL_EXT_TEXTURE_ARRAY) && Is_Extension_Enabled(OGL_ARB_DRAW_ELEMENTS_BASE_VERTEX)) ) {
|
||||
Cmdline_shadow_quality = 0;
|
||||
mprintf((" No hardware support for shadow mapping. Shadows will be disabled. \n"));
|
||||
#ifdef NDEBUG
|
||||
popup(0, 1, POPUP_OK, "No hardware support for shadow mapping. Shadows will be disabled.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( !Cmdline_noglsl && Is_Extension_Enabled(OGL_ARB_SHADER_OBJECTS) && Is_Extension_Enabled(OGL_ARB_FRAGMENT_SHADER)
|
||||
&& Is_Extension_Enabled(OGL_ARB_VERTEX_SHADER) ) {
|
||||
@@ -430,6 +477,14 @@ void opengl_extensions_init()
|
||||
Cmdline_normal = 0;
|
||||
Cmdline_height = 0;
|
||||
Cmdline_postprocess = 0;
|
||||
Cmdline_shadow_quality = 0;
|
||||
Cmdline_no_deferred_lighting = 1;
|
||||
}
|
||||
|
||||
if ( Use_GLSL < 2 || !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) || !Is_Extension_Enabled(OGL_ARB_FLOATING_POINT_TEXTURES) ) {
|
||||
mprintf((" No hardware support for deferred lighting. Deferred lighting will be disabled. \n"));
|
||||
Cmdline_no_deferred_lighting = 1;
|
||||
Cmdline_no_batching = true;
|
||||
}
|
||||
|
||||
if (Use_GLSL) {
|
||||
|
||||
@@ -75,8 +75,15 @@ extern ogl_function GL_EXT_Special[];
|
||||
#define OGL_SM30 24
|
||||
#define OGL_ARB_FLOATING_POINT_TEXTURES 25
|
||||
#define OGL_ARB_DRAW_ELEMENTS_BASE_VERTEX 26
|
||||
#define OGL_EXT_FRAMEBUFFER_BLIT 27
|
||||
#define OGL_EXT_GEOMETRY_SHADER4 28
|
||||
#define OGL_EXT_TEXTURE_ARRAY 29
|
||||
#define OGL_ARB_UNIFORM_BUFFER_OBJECT 30
|
||||
#define OGL_EXT_TRANSFORM_FEEDBACK 31
|
||||
#define OGL_ARB_DRAW_INSTANCED 32
|
||||
#define OGL_ARB_TEXTURE_BUFFER 33
|
||||
|
||||
#define NUM_OGL_EXTENSIONS 27
|
||||
#define NUM_OGL_EXTENSIONS 34
|
||||
|
||||
|
||||
// Functions
|
||||
@@ -147,9 +154,29 @@ extern ogl_function GL_EXT_Special[];
|
||||
#define OGL_DRAW_RANGE_ELEMENTS_BASE_VERTEX 60
|
||||
#define OGL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX 61
|
||||
#define OGL_MULTI_DRAW_ELEMENTS_BASE_VERTEX 62
|
||||
#define OGL_BLITFRAMEBUFFER 63
|
||||
#define OGL_PROGRAM_PARAMETERI 64
|
||||
#define OGL_TEXIMAGE3D 65
|
||||
#define OGL_FRAMEBUFFER_TEXTURE 66
|
||||
#define OGL_GET_UNIFORM_INDICES 67
|
||||
#define OGL_GET_ACTIVE_UNIFORMS_IV 68
|
||||
#define OGL_GET_ACTIVE_UNIFORM_NAME 69
|
||||
#define OGL_GET_UNIFORM_BLOCK_INDEX 70
|
||||
#define OGL_GET_ACTIVE_UNIFORM_BLOCK_IV 71
|
||||
#define OGL_GET_ACTIVE_UNIFORM_BLOCK_NAME 72
|
||||
#define OGL_UNIFORM_BLOCK_BINDING 73
|
||||
#define OGL_BEGIN_TRANSFORM_FEEDBACK 74
|
||||
#define OGL_END_TRANSFORM_FEEDBACK 75
|
||||
#define OGL_BIND_BUFFER_RANGE 76
|
||||
#define OGL_BIND_BUFFER_OFFSET 77
|
||||
#define OGL_BIND_BUFFER_BASE 78
|
||||
#define OGL_TRANSFORM_FEEDBACK_VARYINGS 79
|
||||
#define OGL_GET_TRANSFORM_FEEDBACK_VARYING 80
|
||||
#define OGL_ARB_DRAW_ARRAYS_INSTANCED 81
|
||||
#define OGL_ARB_DRAW_ELEMENTS_INSTANCED 82
|
||||
#define OGL_ARB_TEX_BUFFER 83
|
||||
|
||||
#define NUM_OGL_FUNCTIONS 63
|
||||
|
||||
#define NUM_OGL_FUNCTIONS 84
|
||||
|
||||
// special extensions/functions (OS specific, non-GL stuff)
|
||||
#define OGL_SPC_WGL_SWAP_INTERVAL 0
|
||||
@@ -175,8 +202,14 @@ void opengl_extensions_init();
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
// special one, since it's a core feature
|
||||
// !-----REMOVE WHEN WE MIGRATE TO THE OPENGL CORE PROFILE-----!
|
||||
typedef void (* glDrawRangeElementsProcPtr) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
typedef void (* glTexBufferARBProcPtr) (GLenum target, GLenum internalformat, GLuint buffer);
|
||||
typedef GLuint (* glGetUniformBlockIndexARBProcPtr) (GLuint program, const GLchar *uniformBlockName);
|
||||
|
||||
#define GL_TEXTURE_BUFFER_ARB 0x8C2A
|
||||
#define GL_UNIFORM_BUFFER 0x8A11
|
||||
// !-----REMOVE WHEN WE MIGRATE TO THE OPENGL CORE PROFILE-----!
|
||||
|
||||
// OS X doesn't have the PFN* names so we have to use the real OSX function ptrs
|
||||
#define PFNGLFOGCOORDFEXTPROC glFogCoordfEXTProcPtr
|
||||
@@ -236,9 +269,9 @@ typedef void (* glDrawRangeElementsProcPtr) (GLenum mode, GLuint start, GLuint e
|
||||
#define PFNGLUNIFORM1FARBPROC glUniform1fARBProcPtr
|
||||
#define PFNGLUNIFORM2FARBPROC glUniform2fARBProcPtr
|
||||
#define PFNGLUNIFORM3FARBPROC glUniform3fARBProcPtr
|
||||
#define PFNGLUNIFORM4FARBPROC glUnifrom4fARBProcPtr
|
||||
#define PFNGLUNIFORM4FARBPROC glUniform4fARBProcPtr
|
||||
#define PFNGLUNIFORM3FVARBPROC glUniform3fvARBProcPtr
|
||||
#define PFNGLUNIFORM4FVARBPROC glUnifrom4fvARBProcPtr
|
||||
#define PFNGLUNIFORM4FVARBPROC glUniform4fvARBProcPtr
|
||||
#define PFNGLUNIFORM1IARBPROC glUniform1iARBProcPtr
|
||||
#define PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARBProcPtr
|
||||
#define PFNGLDRAWBUFFERSPROC glDrawBuffersARBProcPtr
|
||||
@@ -246,6 +279,26 @@ typedef void (* glDrawRangeElementsProcPtr) (GLenum mode, GLuint start, GLuint e
|
||||
#define PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glDrawRangeElementsBaseVertexProcPtr
|
||||
#define PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertexProcPtr
|
||||
#define PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glMultiDrawElementsBaseVertexProcPtr
|
||||
#define PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXTProcPtr
|
||||
#define PFNGLPROGRAMPARAMETERIEXTPROC glProgramParameteriEXTProcPtr
|
||||
#define PFNGLFRAMEBUFFERTEXTUREEXTPROC glFramebufferTextureEXTProcPtr
|
||||
#define PFNGLGETUNIFORMINDICESPROC glGetUniformIndicesARBProcPtr
|
||||
#define PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsivARBProcPtr
|
||||
#define PFNGLGETACTIVEUNIFORMNAMEPROC glGetActiveUniformNameARBProcPtr
|
||||
#define PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndexARBProcPtr
|
||||
#define PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockivARBProcPtr
|
||||
#define PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glGetActiveUniformBlockNameARBProcPtr
|
||||
#define PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBindingARBProcPtr
|
||||
#define PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glBeginTransformFeedbackEXTProcPtr
|
||||
#define PFNGLENDTRANSFORMFEEDBACKEXTPROC glEndTransformFeedbackEXTProcPtr
|
||||
#define PFNGLBINDBUFFERRANGEEXTPROC glBindBufferRangeEXTProcPtr
|
||||
#define PFNGLBINDBUFFEROFFSETEXTPROC glBindBufferOffsetEXTProcPtr
|
||||
#define PFNGLBINDBUFFERBASEEXTPROC glBindBufferBaseEXTProcPtr
|
||||
#define PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glTransformFeedbackVaryingsEXTProcPtr
|
||||
#define PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glGetTransformFeedbackVaryingEXTProcPtr
|
||||
#define PFNGLDRAWARRAYSINSTANCEDARBPROC glDrawArraysInstancedARBProcPtr
|
||||
#define PFNGLDRAWELEMENTSINSTANCEDARBPROC glDrawElementsInstancedARBProcPtr
|
||||
#define PFNGLTEXBUFFERARBPROC glTexBufferARBProcPtr
|
||||
#endif // __APPLE__
|
||||
|
||||
#define vglFogCoordfEXT GLEXT_CALL( OGL_FOG_COORDF, PFNGLFOGCOORDFEXTPROC )
|
||||
@@ -315,6 +368,31 @@ typedef void (* glDrawRangeElementsProcPtr) (GLenum mode, GLuint start, GLuint e
|
||||
#define vglDrawRangeElementsBaseVertex GLEXT_CALL( OGL_DRAW_RANGE_ELEMENTS_BASE_VERTEX, PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC )
|
||||
#define vglDrawElementsInstancedBaseVertex GLEXT_CALL( OGL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX, PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC )
|
||||
#define vglMultiDrawElementsBaseVertex GLEXT_CALL( OGL_MULTI_DRAW_ELEMENTS_BASE_VERTEX, PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC )
|
||||
#define vglBlitFramebufferEXT GLEXT_CALL( OGL_BLITFRAMEBUFFER, PFNGLBLITFRAMEBUFFEREXTPROC )
|
||||
#define vglProgramParameteriEXT GLEXT_CALL( OGL_PROGRAM_PARAMETERI, PFNGLPROGRAMPARAMETERIEXTPROC )
|
||||
#define vglGetUniformIndicesARB GLEXT_CALL( OGL_GET_UNIFORM_INDICES, PFNGLGETUNIFORMINDICESPROC )
|
||||
#define vglGetActiveUniformsivARB GLEXT_CALL( OGL_GET_ACTIVE_UNIFORMS_IV, PFNGLGETACTIVEUNIFORMSIVPROC )
|
||||
#define vglGetActiveUniformNameARB GLEXT_CALL( OGL_GET_ACTIVE_UNIFORM_NAME, PFNGLGETACTIVEUNIFORMNAMEPROC )
|
||||
#define vglGetUniformBlockIndexARB GLEXT_CALL2( OGL_GET_UNIFORM_BLOCK_INDEX, PFNGLGETUNIFORMBLOCKINDEXPROC )
|
||||
#define vglGetActiveUniformBlockivARB GLEXT_CALL( OGL_GET_ACTIVE_UNIFORM_BLOCK_IV, PFNGLGETACTIVEUNIFORMBLOCKIVPROC )
|
||||
#define vglGetActiveUniformBlockNameARB GLEXT_CALL( OGL_GET_ACTIVE_UNIFORM_BLOCK_NAME, PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC )
|
||||
#define vglUniformBlockBindingARB GLEXT_CALL( OGL_UNIFORM_BLOCK_BINDING, PFNGLUNIFORMBLOCKBINDINGPROC )
|
||||
#define vglBeginTransformFeedbackEXT GLEXT_CALL( OGL_BEGIN_TRANSFORM_FEEDBACK, PFNGLBEGINTRANSFORMFEEDBACKEXTPROC )
|
||||
#define vglEndTransformFeedbackEXT GLEXT_CALL( OGL_END_TRANSFORM_FEEDBACK, PFNGLENDTRANSFORMFEEDBACKEXTPROC )
|
||||
#define vglBindBufferRangeEXT GLEXT_CALL( OGL_BIND_BUFFER_RANGE, PFNGLBINDBUFFERRANGEEXTPROC )
|
||||
#define vglBindBufferOffsetEXT GLEXT_CALL( OGL_BIND_BUFFER_OFFSET, PFNGLBINDBUFFEROFFSETEXTPROC )
|
||||
#define vglBindBufferBaseEXT GLEXT_CALL( OGL_BIND_BUFFER_BASE, PFNGLBINDBUFFERBASEEXTPROC )
|
||||
#define vglTransformFeedbackVaryingsEXT GLEXT_CALL( OGL_TRANSFORM_FEEDBACK_VARYINGS, PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC )
|
||||
#define vglGetTransformFeedbackVaryingEXT GLEXT_CALL( OGL_GET_TRANSFORM_FEEDBACK_VARYING, PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC )
|
||||
#define vglDrawArraysInstancedARB GLEXT_CALL( OGL_ARB_DRAW_ARRAYS_INSTANCED, PFNGLDRAWARRAYSINSTANCEDARBPROC )
|
||||
#define vglDrawElementsInstancedARB GLEXT_CALL( OGL_ARB_DRAW_ELEMENTS_INSTANCED, PFNGLDRAWELEMENTSINSTANCEDARBPROC )
|
||||
#define vglTexBufferARB GLEXT_CALL( OGL_ARB_TEX_BUFFER, PFNGLTEXBUFFERARBPROC )
|
||||
#ifndef __APPLE__
|
||||
#define vglTexImage3D GLEXT_CALL( OGL_TEXIMAGE3D, PFNGLTEXIMAGE3DPROC )
|
||||
#else
|
||||
#define vglTexImage3D glTexImage3D
|
||||
#endif
|
||||
#define vglFramebufferTextureEXT GLEXT_CALL( OGL_FRAMEBUFFER_TEXTURE, PFNGLFRAMEBUFFERTEXTUREEXTPROC )
|
||||
|
||||
// special extensions
|
||||
#define vwglSwapIntervalEXT GLEXT_SPC_CALL( OGL_SPC_WGL_SWAP_INTERVAL, PFNWGLSWAPINTERVALEXTPROC )
|
||||
|
||||
@@ -31,6 +31,7 @@ opengl_light *opengl_lights = NULL;
|
||||
bool lighting_is_enabled = true;
|
||||
int Num_active_gl_lights = 0;
|
||||
int GL_center_alpha = 0;
|
||||
float GL_light_factor = 1.0f;
|
||||
|
||||
extern float static_point_factor;
|
||||
extern float static_light_factor;
|
||||
@@ -144,6 +145,9 @@ void FSLight2GLLight(light *FSLight, opengl_light *GLLight)
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LT_CONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
Int3();
|
||||
@@ -151,7 +155,6 @@ void FSLight2GLLight(light *FSLight, opengl_light *GLLight)
|
||||
}
|
||||
}
|
||||
|
||||
extern float Interp_light;
|
||||
void opengl_set_light(int light_num, opengl_light *ltp)
|
||||
{
|
||||
Assert(light_num < GL_max_lights);
|
||||
@@ -159,10 +162,11 @@ void opengl_set_light(int light_num, opengl_light *ltp)
|
||||
GLfloat diffuse[4];
|
||||
memcpy(diffuse, ltp->Diffuse, sizeof(GLfloat) * 4);
|
||||
|
||||
if ( (ltp->type == LT_DIRECTIONAL) && (Interp_light < 1.0f) ) {
|
||||
diffuse[0] *= Interp_light;
|
||||
diffuse[1] *= Interp_light;
|
||||
diffuse[2] *= Interp_light;
|
||||
if ( !Use_GLSL && (ltp->type == LT_DIRECTIONAL) && (GL_light_factor < 1.0f) ) {
|
||||
// if we're not using shaders, manually adjust the diffuse light factor.
|
||||
diffuse[0] *= GL_light_factor;
|
||||
diffuse[1] *= GL_light_factor;
|
||||
diffuse[2] *= GL_light_factor;
|
||||
}
|
||||
|
||||
glLightfv(GL_LIGHT0+light_num, GL_POSITION, ltp->Position);
|
||||
@@ -311,7 +315,9 @@ void opengl_change_active_lights(int pos, int d_offset)
|
||||
glScalef(1.0f, 1.0f, -1.0f);
|
||||
|
||||
//Valathil: Sort lights by priority
|
||||
opengl_pre_render_init_lights();
|
||||
extern bool Deferred_lighting;
|
||||
if(!Deferred_lighting)
|
||||
opengl_pre_render_init_lights();
|
||||
|
||||
for (i = 0; i < GL_max_lights; i++) {
|
||||
if ( (offset + i) >= Num_active_gl_lights ) {
|
||||
@@ -449,6 +455,11 @@ void gr_opengl_set_center_alpha(int type)
|
||||
GL_center_alpha = 0;
|
||||
}
|
||||
|
||||
void gr_opengl_set_light_factor(float factor)
|
||||
{
|
||||
GL_light_factor = factor;
|
||||
}
|
||||
|
||||
void gr_opengl_reset_lighting()
|
||||
{
|
||||
int i;
|
||||
@@ -460,6 +471,7 @@ void gr_opengl_reset_lighting()
|
||||
|
||||
for (i = 0; i < GL_max_lights; i++) {
|
||||
GL_state.Light(i, GL_FALSE);
|
||||
opengl_lights[i].occupied = false;
|
||||
}
|
||||
|
||||
Num_active_gl_lights = 0;
|
||||
|
||||
@@ -45,6 +45,7 @@ extern bool lighting_is_enabled;
|
||||
extern GLint GL_max_lights;
|
||||
extern int Num_active_gl_lights;
|
||||
extern int GL_center_alpha;
|
||||
extern float GL_light_factor;
|
||||
|
||||
//Functions
|
||||
int gr_opengl_make_light(light *fs_light, int idx, int priority); //unused -- stub function
|
||||
@@ -56,6 +57,7 @@ void gr_opengl_set_lighting(bool set, bool state);
|
||||
void gr_opengl_center_alpha(int type);
|
||||
void gr_opengl_set_center_alpha(int type);
|
||||
void gr_opengl_set_ambient_light(int red, int green, int blue);
|
||||
void gr_opengl_set_light_factor(float factor);
|
||||
|
||||
void opengl_change_active_lights(int pos, int d_offset = 0);
|
||||
void opengl_light_init();
|
||||
|
||||
@@ -37,58 +37,6 @@ float ls_intensity = 0.5f;
|
||||
float ls_cpintensity = 0.5f * 50 * 0.02f;
|
||||
int ls_samplenum = 50;
|
||||
|
||||
#define SDR_POST_FLAG_MAIN (1<<0)
|
||||
#define SDR_POST_FLAG_BRIGHT (1<<1)
|
||||
#define SDR_POST_FLAG_BLUR (1<<2)
|
||||
#define SDR_POST_FLAG_PASS1 (1<<3)
|
||||
#define SDR_POST_FLAG_PASS2 (1<<4)
|
||||
#define SDR_POST_FLAG_LIGHTSHAFT (1<<5)
|
||||
|
||||
static SCP_vector<opengl_shader_t> GL_post_shader;
|
||||
|
||||
struct opengl_shader_file_t {
|
||||
char *vert;
|
||||
char *frag;
|
||||
|
||||
int flags;
|
||||
|
||||
int num_uniforms;
|
||||
char* uniforms[MAX_SHADER_UNIFORMS];
|
||||
|
||||
int num_attributes;
|
||||
char* attributes[MAX_SDR_ATTRIBUTES];
|
||||
};
|
||||
|
||||
// NOTE: The order of this list *must* be preserved! Additional shaders can be
|
||||
// added, but the first 7 are used with magic numbers so their position
|
||||
// is assumed to never change.
|
||||
static opengl_shader_file_t GL_post_shader_files[] = {
|
||||
// NOTE: the main post-processing shader has any number of uniforms, but
|
||||
// these few should always be present
|
||||
{ "post-v.sdr", "post-f.sdr", SDR_POST_FLAG_MAIN,
|
||||
5, { "tex", "depth_tex", "timer", "bloomed", "bloom_intensity" }, 0, { NULL } },
|
||||
|
||||
{ "post-v.sdr", "blur-f.sdr", SDR_POST_FLAG_BLUR | SDR_POST_FLAG_PASS1,
|
||||
2, { "tex", "bsize" }, 0, { NULL } },
|
||||
|
||||
{ "post-v.sdr", "blur-f.sdr", SDR_POST_FLAG_BLUR | SDR_POST_FLAG_PASS2,
|
||||
2, { "tex", "bsize" }, 0, { NULL } },
|
||||
|
||||
{ "post-v.sdr", "brightpass-f.sdr", SDR_POST_FLAG_BRIGHT,
|
||||
1, { "tex" }, 0, { NULL } },
|
||||
|
||||
{ "fxaa-v.sdr", "fxaa-f.sdr", 0,
|
||||
3, { "tex0", "rt_w", "rt_h"}, 0, { NULL } },
|
||||
|
||||
{ "post-v.sdr", "fxaapre-f.sdr", 0,
|
||||
1, { "tex"}, 0, { NULL } },
|
||||
|
||||
{ "post-v.sdr", "ls-f.sdr", SDR_POST_FLAG_LIGHTSHAFT,
|
||||
8, { "scene", "cockpit", "sun_pos", "weight", "intensity", "falloff", "density", "cp_intensity" }, 0, { NULL } }
|
||||
};
|
||||
|
||||
static const unsigned int Num_post_shader_files = sizeof(GL_post_shader_files) / sizeof(opengl_shader_file_t);
|
||||
|
||||
typedef struct post_effect_t {
|
||||
SCP_string name;
|
||||
SCP_string uniform_name;
|
||||
@@ -114,18 +62,17 @@ static int Post_initialized = 0;
|
||||
|
||||
bool Post_in_frame = false;
|
||||
|
||||
static int Post_active_shader_index = 0;
|
||||
static int Post_active_shader_index = -1;
|
||||
|
||||
static GLuint Post_framebuffer_id[2] = { 0 };
|
||||
static GLuint Post_bloom_texture_id[3] = { 0 };
|
||||
static GLuint Post_shadow_framebuffer_id = 0;
|
||||
static GLuint Post_shadow_texture_id = 0;
|
||||
static GLuint Post_shadow_depth_texture_id = 0;
|
||||
|
||||
static int Post_texture_width = 0;
|
||||
static int Post_texture_height = 0;
|
||||
|
||||
|
||||
static char *opengl_post_load_shader(char *filename, int flags, int flags2);
|
||||
|
||||
|
||||
static bool opengl_post_pass_bloom()
|
||||
{
|
||||
if (Cmdline_bloom_intensity <= 0) {
|
||||
@@ -148,9 +95,9 @@ static bool opengl_post_pass_bloom()
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
opengl_shader_set_current( &GL_post_shader[3] );
|
||||
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BRIGHTPASS, 0) );
|
||||
|
||||
vglUniform1iARB( opengl_shader_get_uniform("tex"), 0 );
|
||||
GL_state.Uniform.setUniformi( "tex", 0 );
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
@@ -182,10 +129,14 @@ static bool opengl_post_pass_bloom()
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
opengl_shader_set_current( &GL_post_shader[1+pass] );
|
||||
if ( pass ) {
|
||||
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLUR, SDR_FLAG_BLUR_VERTICAL) );
|
||||
} else {
|
||||
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLUR, SDR_FLAG_BLUR_HORIZONTAL) );
|
||||
}
|
||||
|
||||
vglUniform1iARB( opengl_shader_get_uniform("tex"), 0 );
|
||||
vglUniform1fARB( opengl_shader_get_uniform("bsize"), (pass) ? (float)width : (float)height );
|
||||
GL_state.Uniform.setUniformi( "tex", 0 );
|
||||
GL_state.Uniform.setUniformf( "bsize", (pass) ? (float)width : (float)height );
|
||||
|
||||
GL_state.Texture.Enable(Post_bloom_texture_id[pass]);
|
||||
|
||||
@@ -227,8 +178,7 @@ void gr_opengl_post_process_begin()
|
||||
|
||||
// Assert( !opengl_check_framebuffer() );
|
||||
|
||||
GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
|
||||
vglDrawBuffers(2, buffers);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
@@ -237,44 +187,15 @@ void gr_opengl_post_process_begin()
|
||||
}
|
||||
|
||||
void recompile_fxaa_shader() {
|
||||
char *vert = NULL, *frag = NULL;
|
||||
opengl_shader_t *new_shader = &GL_post_shader[fxaa_shader_id];
|
||||
opengl_shader_file_t *shader_file = &GL_post_shader_files[4];
|
||||
|
||||
// choose appropriate files
|
||||
char *vert_name = shader_file->vert;
|
||||
char *frag_name = shader_file->frag;
|
||||
|
||||
mprintf(("Recompiling FXAA shader with preset %d\n", Cmdline_fxaa_preset));
|
||||
|
||||
// read vertex shader
|
||||
vert = opengl_post_load_shader(vert_name, shader_file->flags, 0);
|
||||
// start recompile by grabbing deleting the current shader we have, assuming it's already created
|
||||
opengl_delete_shader( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) );
|
||||
|
||||
// read fragment shader
|
||||
frag = opengl_post_load_shader(frag_name, shader_file->flags, 0);
|
||||
// then recreate it again. shader loading code will be updated with the new FXAA presets
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0);
|
||||
|
||||
|
||||
Verify( vert != NULL );
|
||||
Verify( frag != NULL );
|
||||
|
||||
new_shader->program_id = opengl_shader_create(vert, frag);
|
||||
|
||||
if ( !new_shader->program_id ) {
|
||||
}
|
||||
|
||||
|
||||
new_shader->flags = shader_file->flags;
|
||||
new_shader->flags2 = 0;
|
||||
|
||||
opengl_shader_set_current( new_shader );
|
||||
|
||||
new_shader->uniforms.reserve(shader_file->num_uniforms);
|
||||
|
||||
for (int i = 0; i < shader_file->num_uniforms; i++) {
|
||||
opengl_shader_init_uniform( shader_file->uniforms[i] );
|
||||
}
|
||||
|
||||
opengl_shader_set_current();
|
||||
Fxaa_preset_last_frame = Cmdline_fxaa_preset;
|
||||
}
|
||||
|
||||
@@ -289,10 +210,10 @@ void opengl_post_pass_fxaa() {
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
|
||||
// Do a prepass to convert the main shaders' RGBA output into RGBL
|
||||
opengl_shader_set_current( &GL_post_shader[fxaa_shader_id + 1] );
|
||||
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0) );
|
||||
|
||||
// basic/default uniforms
|
||||
vglUniform1iARB( opengl_shader_get_uniform("tex"), 0 );
|
||||
GL_state.Uniform.setUniformi( "tex", 0 );
|
||||
|
||||
vglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Scene_luminance_texture, 0);
|
||||
|
||||
@@ -305,14 +226,14 @@ void opengl_post_pass_fxaa() {
|
||||
GL_state.Texture.Disable();
|
||||
|
||||
// set and configure post shader ..
|
||||
opengl_shader_set_current( &GL_post_shader[fxaa_shader_id] );
|
||||
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) );
|
||||
|
||||
vglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Scene_color_texture, 0);
|
||||
|
||||
// basic/default uniforms
|
||||
vglUniform1iARB( opengl_shader_get_uniform("tex0"), 0 );
|
||||
vglUniform1fARB( opengl_shader_get_uniform("rt_w"), static_cast<float>(Post_texture_width));
|
||||
vglUniform1fARB( opengl_shader_get_uniform("rt_h"), static_cast<float>(Post_texture_height));
|
||||
GL_state.Uniform.setUniformi( "tex0", 0 );
|
||||
GL_state.Uniform.setUniformf( "rt_w", static_cast<float>(Post_texture_width));
|
||||
GL_state.Uniform.setUniformf( "rt_h", static_cast<float>(Post_texture_height));
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
@@ -325,9 +246,12 @@ void opengl_post_pass_fxaa() {
|
||||
opengl_shader_set_current();
|
||||
}
|
||||
|
||||
extern GLuint shadow_map[2];
|
||||
extern GLuint Shadow_map_depth_texture;
|
||||
extern GLuint Scene_depth_texture;
|
||||
extern GLuint Cockpit_depth_texture;
|
||||
extern GLuint Scene_position_texture;
|
||||
extern GLuint Scene_normal_texture;
|
||||
extern GLuint Scene_specular_texture;
|
||||
extern bool stars_sun_has_glare(int index);
|
||||
extern float Sun_spot;
|
||||
void gr_opengl_post_process_end()
|
||||
@@ -346,7 +270,7 @@ void gr_opengl_post_process_end()
|
||||
opengl_post_pass_fxaa();
|
||||
}
|
||||
|
||||
opengl_shader_set_current( &GL_post_shader[6] );
|
||||
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_LIGHTSHAFTS, 0) );
|
||||
float x,y;
|
||||
// should we even be here?
|
||||
if (!Game_subspace_effect && ls_on && !ls_force_off)
|
||||
@@ -367,14 +291,14 @@ void gr_opengl_post_process_end()
|
||||
|
||||
x = asin(vm_vec_dot( &light_dir, &Eye_matrix.vec.rvec ))/PI*1.5f+0.5f; //cant get the coordinates right but this works for the limited glare fov
|
||||
y = asin(vm_vec_dot( &light_dir, &Eye_matrix.vec.uvec ))/PI*1.5f*gr_screen.clip_aspect+0.5f;
|
||||
vglUniform2fARB( opengl_shader_get_uniform("sun_pos"), x, y);
|
||||
vglUniform1iARB( opengl_shader_get_uniform("scene"), 0);
|
||||
vglUniform1iARB( opengl_shader_get_uniform("cockpit"), 1);
|
||||
vglUniform1fARB( opengl_shader_get_uniform("density"), ls_density);
|
||||
vglUniform1fARB( opengl_shader_get_uniform("falloff"), ls_falloff);
|
||||
vglUniform1fARB( opengl_shader_get_uniform("weight"), ls_weight);
|
||||
vglUniform1fARB( opengl_shader_get_uniform("intensity"), Sun_spot * ls_intensity);
|
||||
vglUniform1fARB( opengl_shader_get_uniform("cp_intensity"), Sun_spot * ls_cpintensity);
|
||||
GL_state.Uniform.setUniform2f( "sun_pos", x, y);
|
||||
GL_state.Uniform.setUniformi( "scene", 0);
|
||||
GL_state.Uniform.setUniformi( "cockpit", 1);
|
||||
GL_state.Uniform.setUniformf( "density", ls_density);
|
||||
GL_state.Uniform.setUniformf( "falloff", ls_falloff);
|
||||
GL_state.Uniform.setUniformf( "weight", ls_weight);
|
||||
GL_state.Uniform.setUniformf( "intensity", Sun_spot * ls_intensity);
|
||||
GL_state.Uniform.setUniformf( "cp_intensity", Sun_spot * ls_cpintensity);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
@@ -414,20 +338,33 @@ void gr_opengl_post_process_end()
|
||||
GL_state.Color(255, 255, 255, 255);
|
||||
|
||||
// set and configure post shader ...
|
||||
int flags = 0;
|
||||
for ( int i = 0; i < (int)Post_effects.size(); i++) {
|
||||
if (Post_effects[i].always_on) {
|
||||
flags |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
opengl_shader_set_current( &GL_post_shader[Post_active_shader_index] );
|
||||
int post_sdr_handle = Post_active_shader_index;
|
||||
|
||||
if ( post_sdr_handle < 0 ) {
|
||||
// no active shader index? use the always on shader.
|
||||
post_sdr_handle = gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_MAIN, flags);
|
||||
}
|
||||
|
||||
opengl_shader_set_current(post_sdr_handle);
|
||||
|
||||
// basic/default uniforms
|
||||
vglUniform1iARB( opengl_shader_get_uniform("tex"), 0 );
|
||||
vglUniform1iARB( opengl_shader_get_uniform("depth_tex"), 2);
|
||||
vglUniform1fARB( opengl_shader_get_uniform("timer"), static_cast<float>(timer_get_milliseconds() % 100 + 1) );
|
||||
GL_state.Uniform.setUniformi( "tex", 0 );
|
||||
GL_state.Uniform.setUniformi( "depth_tex", 2);
|
||||
GL_state.Uniform.setUniformf( "timer", static_cast<float>(timer_get_milliseconds() % 100 + 1) );
|
||||
|
||||
for (size_t idx = 0; idx < Post_effects.size(); idx++) {
|
||||
if ( GL_post_shader[Post_active_shader_index].flags2 & (1<<idx) ) {
|
||||
if ( GL_shader[post_sdr_handle].flags & (1<<idx) ) {
|
||||
const char *name = Post_effects[idx].uniform_name.c_str();
|
||||
float value = Post_effects[idx].intensity;
|
||||
|
||||
vglUniform1fARB( opengl_shader_get_uniform(name), value);
|
||||
GL_state.Uniform.setUniformf( name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,17 +377,19 @@ void gr_opengl_post_process_end()
|
||||
intensity /= 3.0f;
|
||||
}
|
||||
|
||||
vglUniform1fARB( opengl_shader_get_uniform("bloom_intensity"), intensity );
|
||||
GL_state.Uniform.setUniformf( "bloom_intensity", intensity );
|
||||
|
||||
vglUniform1iARB( opengl_shader_get_uniform("bloomed"), 1 );
|
||||
GL_state.Uniform.setUniformi( "bloomed", 1 );
|
||||
|
||||
GL_state.Texture.SetActiveUnit(1);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Post_bloom_texture_id[2]);
|
||||
}
|
||||
else
|
||||
GL_state.Uniform.setUniformf( "bloom_intensity", 0.0f );
|
||||
|
||||
// now render it to the screen ...
|
||||
|
||||
vglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Scene_color_texture);
|
||||
@@ -460,11 +399,61 @@ void gr_opengl_post_process_end()
|
||||
GL_state.Texture.Enable(Scene_depth_texture);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
// Done!
|
||||
|
||||
//Shadow Map debug window
|
||||
//#define SHADOW_DEBUG
|
||||
#ifdef SHADOW_DEBUG
|
||||
opengl_shader_set_current( &GL_post_shader[7] );
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
// GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY);
|
||||
// GL_state.Texture.Enable(Shadow_map_depth_texture);
|
||||
extern GLuint Shadow_map_texture;
|
||||
extern GLuint Post_shadow_texture_id;
|
||||
GL_state.Texture.Enable(Shadow_map_texture);
|
||||
vglUniform1iARB( opengl_shader_get_uniform("shadow_map"), 0);
|
||||
vglUniform1iARB( opengl_shader_get_uniform("index"), 0);
|
||||
//opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
//opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.5f);
|
||||
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 1.0f, 1.0f);
|
||||
vglUniform1iARB( opengl_shader_get_uniform("index"), 1);
|
||||
//opengl_draw_textured_quad(-1.0f, -0.5f, 0.5f, 0.0f, -0.5f, 0.0f, 0.75f, 0.25f);
|
||||
opengl_draw_textured_quad(-1.0f, -0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 1.0f, 1.0f);
|
||||
vglUniform1iARB( opengl_shader_get_uniform("index"), 2);
|
||||
opengl_draw_textured_quad(-0.5f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 1.0f, 1.0f);
|
||||
vglUniform1iARB( opengl_shader_get_uniform("index"), 3);
|
||||
opengl_draw_textured_quad(-0.5f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 1.0f, 1.0f);
|
||||
opengl_shader_set_current();
|
||||
#endif
|
||||
|
||||
/*GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Scene_depth_texture);
|
||||
|
||||
|
||||
*/
|
||||
// Done!
|
||||
/*GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Scene_effect_texture);
|
||||
|
||||
opengl_draw_textured_quad(0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Scene_normal_texture);
|
||||
|
||||
opengl_draw_textured_quad(-1.0f, -0.0f, 0.0f, 0.0f, 0.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Scene_specular_texture);
|
||||
|
||||
opengl_draw_textured_quad(0.0f, -0.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
|
||||
*/
|
||||
GL_state.Texture.SetActiveUnit(2);
|
||||
GL_state.Texture.Disable();
|
||||
GL_state.Texture.SetActiveUnit(1);
|
||||
GL_state.Texture.SetActiveUnit(1);
|
||||
GL_state.Texture.Disable();
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.Disable();
|
||||
@@ -492,84 +481,13 @@ void get_post_process_effect_names(SCP_vector<SCP_string> &names)
|
||||
}
|
||||
}
|
||||
|
||||
static bool opengl_post_compile_shader(int flags)
|
||||
void opengl_post_init_uniforms(int flags)
|
||||
{
|
||||
char *vert = NULL, *frag = NULL;
|
||||
bool in_error = false;
|
||||
opengl_shader_t new_shader;
|
||||
opengl_shader_file_t *shader_file = &GL_post_shader_files[0];
|
||||
int num_main_uniforms = 0;
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < (int)Post_effects.size(); idx++) {
|
||||
if ( flags & (1 << idx) ) {
|
||||
num_main_uniforms++;
|
||||
for (int idx = 0; idx < (int)Post_effects.size(); idx++) {
|
||||
if (flags & (1 << idx)) {
|
||||
opengl_shader_init_uniform(Post_effects[idx].uniform_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// choose appropriate files
|
||||
char *vert_name = shader_file->vert;
|
||||
char *frag_name = shader_file->frag;
|
||||
|
||||
mprintf(("POST-PROCESSING: Compiling new post-processing shader with flags %d ... \n", flags));
|
||||
|
||||
// read vertex shader
|
||||
if ( (vert = opengl_post_load_shader(vert_name, shader_file->flags, flags)) == NULL ) {
|
||||
in_error = true;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// read fragment shader
|
||||
if ( (frag = opengl_post_load_shader(frag_name, shader_file->flags, flags)) == NULL ) {
|
||||
in_error = true;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Verify( vert != NULL );
|
||||
Verify( frag != NULL );
|
||||
|
||||
new_shader.program_id = opengl_shader_create(vert, frag);
|
||||
|
||||
if ( !new_shader.program_id ) {
|
||||
in_error = true;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
|
||||
new_shader.flags = shader_file->flags;
|
||||
new_shader.flags2 = flags;
|
||||
|
||||
opengl_shader_set_current( &new_shader );
|
||||
|
||||
new_shader.uniforms.reserve(shader_file->num_uniforms + num_main_uniforms);
|
||||
|
||||
for (idx = 0; idx < shader_file->num_uniforms; idx++) {
|
||||
opengl_shader_init_uniform( shader_file->uniforms[idx] );
|
||||
}
|
||||
|
||||
for (idx = 0; idx < (int)Post_effects.size(); idx++) {
|
||||
if ( flags & (1 << idx) ) {
|
||||
opengl_shader_init_uniform( Post_effects[idx].uniform_name.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
opengl_shader_set_current();
|
||||
|
||||
// add it to our list of embedded shaders
|
||||
GL_post_shader.push_back( new_shader );
|
||||
|
||||
Done:
|
||||
if (vert != NULL) {
|
||||
vm_free(vert);
|
||||
vert = NULL;
|
||||
}
|
||||
|
||||
if (frag != NULL) {
|
||||
vm_free(frag);
|
||||
frag = NULL;
|
||||
}
|
||||
|
||||
return in_error;
|
||||
}
|
||||
|
||||
void gr_opengl_post_process_set_effect(const char *name, int value)
|
||||
@@ -609,29 +527,7 @@ void gr_opengl_post_process_set_effect(const char *name, int value)
|
||||
}
|
||||
}
|
||||
|
||||
// see if any existing shader has those flags
|
||||
for (idx = 0; idx < GL_post_shader.size(); idx++) {
|
||||
if (GL_post_shader[idx].flags2 == sflags) {
|
||||
// no change required
|
||||
need_change = false;
|
||||
|
||||
// set this as the active post shader
|
||||
Post_active_shader_index = (int)idx;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if not then add a new shader to the list
|
||||
if (need_change) {
|
||||
if ( !opengl_post_compile_shader(sflags) ) {
|
||||
// shader added, set it as active
|
||||
Post_active_shader_index = (int)(GL_post_shader.size() - 1);
|
||||
} else {
|
||||
// failed to load, just go with default
|
||||
Post_active_shader_index = 0;
|
||||
}
|
||||
}
|
||||
Post_active_shader_index = gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_MAIN, sflags);
|
||||
}
|
||||
|
||||
void gr_opengl_post_process_set_defaults()
|
||||
@@ -647,24 +543,7 @@ void gr_opengl_post_process_set_defaults()
|
||||
Post_effects[idx].intensity = Post_effects[idx].default_intensity;
|
||||
}
|
||||
|
||||
// remove any post shaders created on-demand, leaving only the defaults
|
||||
list_size = GL_post_shader.size();
|
||||
|
||||
for (idx = list_size-1; idx > 0; idx--) {
|
||||
if ( !(GL_post_shader[idx].flags & SDR_POST_FLAG_MAIN) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (GL_post_shader[idx].program_id) {
|
||||
vglDeleteObjectARB(GL_post_shader[idx].program_id);
|
||||
}
|
||||
|
||||
GL_post_shader[idx].uniforms.clear();
|
||||
|
||||
GL_post_shader.pop_back();
|
||||
}
|
||||
|
||||
Post_active_shader_index = 0;
|
||||
Post_active_shader_index = -1;
|
||||
}
|
||||
|
||||
extern GLuint Cockpit_depth_texture;
|
||||
@@ -801,39 +680,22 @@ static bool opengl_post_init_table()
|
||||
}
|
||||
}
|
||||
|
||||
static char *opengl_post_load_shader(char *filename, int flags, int flags2)
|
||||
void opengl_post_load_shader(SCP_string &sflags, shader_type shader, int flags)
|
||||
{
|
||||
SCP_string sflags;
|
||||
|
||||
if (Use_GLSL >= 4) {
|
||||
sflags += "#define SHADER_MODEL 4\n";
|
||||
} else if (Use_GLSL == 3) {
|
||||
sflags += "#define SHADER_MODEL 3\n";
|
||||
} else {
|
||||
sflags += "#define SHADER_MODEL 2\n";
|
||||
}
|
||||
|
||||
for (size_t idx = 0; idx < Post_effects.size(); idx++) {
|
||||
if ( flags2 & (1 << idx) ) {
|
||||
sflags += "#define ";
|
||||
sflags += Post_effects[idx].define_name.c_str();
|
||||
sflags += "\n";
|
||||
if ( shader == SDR_TYPE_POST_PROCESS_MAIN ) {
|
||||
for (size_t idx = 0; idx < Post_effects.size(); idx++) {
|
||||
if (flags & (1 << idx)) {
|
||||
sflags += "#define ";
|
||||
sflags += Post_effects[idx].define_name.c_str();
|
||||
sflags += "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & SDR_POST_FLAG_PASS1) {
|
||||
sflags += "#define PASS_0\n";
|
||||
} else if (flags & SDR_POST_FLAG_PASS2) {
|
||||
sflags += "#define PASS_1\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_POST_FLAG_LIGHTSHAFT) {
|
||||
char temp[42];
|
||||
} else if ( shader == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS ) {
|
||||
char temp[64];
|
||||
sprintf(temp, "#define SAMPLE_NUM %d\n", ls_samplenum);
|
||||
sflags += temp;
|
||||
}
|
||||
|
||||
switch (Cmdline_fxaa_preset) {
|
||||
} else if ( shader == SDR_TYPE_POST_PROCESS_FXAA ) {
|
||||
switch (Cmdline_fxaa_preset) {
|
||||
case 0:
|
||||
sflags += "#define FXAA_QUALITY_PRESET 10\n";
|
||||
sflags += "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0)\n";
|
||||
@@ -895,150 +757,42 @@ static char *opengl_post_load_shader(char *filename, int flags, int flags2)
|
||||
sflags += "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/32.0)\n";
|
||||
sflags += "#define FXAA_QUALITY_SUBPIX 0.33\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char *shader_flags = sflags.c_str();
|
||||
int flags_len = strlen(shader_flags);
|
||||
|
||||
if (Enable_external_shaders && stricmp(filename, "fxaapre-f.sdr") && stricmp(filename, "fxaa-f.sdr") && stricmp(filename, "fxaa-v.sdr")) {
|
||||
CFILE *cf_shader = cfopen(filename, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS);
|
||||
|
||||
if (cf_shader != NULL ) {
|
||||
int len = cfilelength(cf_shader);
|
||||
char *shader = (char*) vm_malloc(len + flags_len + 1);
|
||||
|
||||
strcpy(shader, shader_flags);
|
||||
memset(shader + flags_len, 0, len + 1);
|
||||
cfread(shader + flags_len, len + 1, 1, cf_shader);
|
||||
cfclose(cf_shader);
|
||||
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
|
||||
mprintf((" Loading built-in default shader for: %s\n", filename));
|
||||
char* def_shader = defaults_get_file(filename);
|
||||
size_t len = strlen(def_shader);
|
||||
char *shader = (char*) vm_malloc(len + flags_len + 1);
|
||||
|
||||
strcpy(shader, shader_flags);
|
||||
strcat(shader, def_shader);
|
||||
//memset(shader + flags_len, 0, len + 1);
|
||||
|
||||
return shader;
|
||||
|
||||
}
|
||||
|
||||
static bool opengl_post_init_shader()
|
||||
bool opengl_post_init_shaders()
|
||||
{
|
||||
char *vert = NULL, *frag = NULL;
|
||||
bool rval = true;
|
||||
int idx, i;
|
||||
int flags2 = 0;
|
||||
int num_main_uniforms = 0;
|
||||
int idx;
|
||||
int flags = 0;
|
||||
|
||||
// figure out which flags we need for the main post process shader
|
||||
for (idx = 0; idx < (int)Post_effects.size(); idx++) {
|
||||
if (Post_effects[idx].always_on) {
|
||||
flags2 |= (1 << idx);
|
||||
num_main_uniforms++;
|
||||
flags |= (1 << idx);
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < (int)Num_post_shader_files; idx++) {
|
||||
bool in_error = false;
|
||||
opengl_shader_t new_shader;
|
||||
opengl_shader_file_t *shader_file = &GL_post_shader_files[idx];
|
||||
|
||||
// choose appropriate files
|
||||
char *vert_name = shader_file->vert;
|
||||
char *frag_name = shader_file->frag;
|
||||
|
||||
mprintf((" Compiling post-processing shader %d ... \n", idx+1));
|
||||
|
||||
// read vertex shader
|
||||
if ( (vert = opengl_post_load_shader(vert_name, shader_file->flags, flags2)) == NULL ) {
|
||||
in_error = true;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
// read fragment shader
|
||||
if ( (frag = opengl_post_load_shader(frag_name, shader_file->flags, flags2)) == NULL ) {
|
||||
in_error = true;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Verify( vert != NULL );
|
||||
Verify( frag != NULL );
|
||||
|
||||
new_shader.program_id = opengl_shader_create(vert, frag);
|
||||
|
||||
if ( !new_shader.program_id ) {
|
||||
in_error = true;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
|
||||
new_shader.flags = shader_file->flags;
|
||||
new_shader.flags2 = flags2;
|
||||
|
||||
opengl_shader_set_current( &new_shader );
|
||||
|
||||
new_shader.uniforms.reserve(shader_file->num_uniforms + num_main_uniforms);
|
||||
|
||||
for (i = 0; i < shader_file->num_uniforms; i++) {
|
||||
opengl_shader_init_uniform( shader_file->uniforms[i] );
|
||||
}
|
||||
|
||||
if (idx == 0) {
|
||||
for (i = 0; i < (int)Post_effects.size(); i++) {
|
||||
if ( flags2 & (1 << i) ) {
|
||||
opengl_shader_init_uniform( Post_effects[i].uniform_name.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
flags2 = 0;
|
||||
num_main_uniforms = 0;
|
||||
}
|
||||
|
||||
|
||||
opengl_shader_set_current();
|
||||
|
||||
// add it to our list of embedded shaders
|
||||
GL_post_shader.push_back( new_shader );
|
||||
|
||||
Done:
|
||||
if (vert != NULL) {
|
||||
vm_free(vert);
|
||||
vert = NULL;
|
||||
}
|
||||
|
||||
if (frag != NULL) {
|
||||
vm_free(frag);
|
||||
frag = NULL;
|
||||
}
|
||||
|
||||
if (idx == 4)
|
||||
fxaa_shader_id = GL_post_shader.size() - 1;
|
||||
|
||||
if (in_error) {
|
||||
if (idx == 0) {
|
||||
// only the main/first shader is actually required for post-processing
|
||||
rval = false;
|
||||
break;
|
||||
} else if (idx == 4) {
|
||||
Cmdline_fxaa = false;
|
||||
fxaa_unavailable = true;
|
||||
mprintf(("Error while compiling FXAA shaders. FXAA will be unavailable.\n"));
|
||||
} else if ( shader_file->flags & (SDR_POST_FLAG_BLUR|SDR_POST_FLAG_BRIGHT) ) {
|
||||
// disable bloom if we don't have those shaders available
|
||||
Cmdline_bloom_intensity = 0;
|
||||
}
|
||||
}
|
||||
if ( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_MAIN, flags) < 0 ) {
|
||||
// only the main shader is actually required for post-processing
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BRIGHTPASS, 0) < 0 ||
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLUR, SDR_FLAG_BLUR_HORIZONTAL) < 0 ||
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLUR, SDR_FLAG_BLUR_VERTICAL) < 0 ) {
|
||||
// disable bloom if we don't have those shaders available
|
||||
Cmdline_bloom_intensity = 0;
|
||||
}
|
||||
|
||||
mprintf(("\n"));
|
||||
if ( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) < 0 ||
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0) < 0 ) {
|
||||
Cmdline_fxaa = false;
|
||||
fxaa_unavailable = true;
|
||||
mprintf(("Error while compiling FXAA shaders. FXAA will be unavailable.\n"));
|
||||
}
|
||||
|
||||
return rval;
|
||||
return true;
|
||||
}
|
||||
|
||||
// generate and test the framebuffer and textures that we are going to use
|
||||
@@ -1131,6 +885,61 @@ static bool opengl_post_init_framebuffer()
|
||||
}
|
||||
}
|
||||
|
||||
if ( Cmdline_shadow_quality ) {
|
||||
int size = (Cmdline_shadow_quality == 2 ? 1024 : 512);
|
||||
|
||||
vglGenFramebuffersEXT(1, &Post_shadow_framebuffer_id);
|
||||
vglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Post_shadow_framebuffer_id);
|
||||
|
||||
glGenTextures(1, &Post_shadow_texture_id);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY_EXT);
|
||||
// GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Post_shadow_texture_id);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
vglTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGBA32F_ARB, size, size, 4, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, size, size, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
// vglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Post_shadow_texture_id, 0);
|
||||
vglFramebufferTextureEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, Post_shadow_texture_id, 0);
|
||||
|
||||
glGenTextures(1, &Post_shadow_depth_texture_id);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY_EXT);
|
||||
// GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Post_shadow_depth_texture_id);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
vglTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_DEPTH_COMPONENT32, size, size, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
// glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, size, size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
|
||||
// vglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, Post_shadow_depth_texture_id, 0);
|
||||
vglFramebufferTextureEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, Post_shadow_depth_texture_id, 0);
|
||||
}
|
||||
|
||||
vglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
GL_state.Texture.Disable();
|
||||
@@ -1177,7 +986,7 @@ void opengl_post_process_init()
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !opengl_post_init_shader() ) {
|
||||
if ( !opengl_post_init_shaders() ) {
|
||||
mprintf((" Unable to initialize post-processing shaders! Disabling post-processing...\n\n"));
|
||||
Cmdline_postprocess = 0;
|
||||
return;
|
||||
@@ -1198,17 +1007,6 @@ void opengl_post_process_shutdown()
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < GL_post_shader.size(); i++) {
|
||||
if (GL_post_shader[i].program_id) {
|
||||
vglDeleteObjectARB(GL_post_shader[i].program_id);
|
||||
GL_post_shader[i].program_id = 0;
|
||||
}
|
||||
|
||||
GL_post_shader[i].uniforms.clear();
|
||||
}
|
||||
|
||||
GL_post_shader.clear();
|
||||
|
||||
if (Post_bloom_texture_id[0]) {
|
||||
glDeleteTextures(3, Post_bloom_texture_id);
|
||||
memset(Post_bloom_texture_id, 0, sizeof(Post_bloom_texture_id));
|
||||
|
||||
@@ -12,5 +12,7 @@ void gr_opengl_post_process_begin();
|
||||
void gr_opengl_post_process_end();
|
||||
void get_post_process_effect_names(SCP_vector<SCP_string> &names);
|
||||
|
||||
void opengl_post_init_uniforms(int flags);
|
||||
void opengl_post_load_shader(SCP_string &sflags, shader_type shader, int flags);
|
||||
|
||||
#endif // _GROPENGLPOSTPROCESSING_H
|
||||
+415
-205
@@ -29,51 +29,150 @@
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "mod_table/mod_table.h"
|
||||
|
||||
|
||||
SCP_vector<opengl_shader_t> GL_shader;
|
||||
|
||||
static char *GLshader_info_log = NULL;
|
||||
static const int GLshader_info_log_size = 8192;
|
||||
GLuint Framebuffer_fallback_texture_id = 0;
|
||||
|
||||
static int Effect_num = 0;
|
||||
static float Anim_timer = 0.0f;
|
||||
static int GL_anim_effect_num = 0;
|
||||
static float GL_anim_timer = 0.0f;
|
||||
|
||||
geometry_sdr_params *Current_geo_sdr_params = NULL;
|
||||
|
||||
/**
|
||||
* Static lookup reference for main shader uniforms
|
||||
* When adding a new SDR_ flag, list all associated uniforms and attributes here
|
||||
* Static lookup reference for shader uniforms
|
||||
* When adding a new shader, list all associated uniforms and attributes here
|
||||
*/
|
||||
static opengl_shader_uniform_reference_t GL_Uniform_Reference_Main[] = {
|
||||
{ SDR_FLAG_LIGHT, 1, {"n_lights"}, 0, { NULL }, "Lighting" },
|
||||
{ SDR_FLAG_FOG, 0, { NULL }, 0, { NULL }, "Fog Effect" },
|
||||
{ SDR_FLAG_DIFFUSE_MAP, 5, {"sBasemap", "desaturate", "desaturate_r", "desaturate_g", "desaturate_b"}, 0, { NULL }, "Diffuse Mapping"},
|
||||
{ SDR_FLAG_GLOW_MAP, 1, {"sGlowmap"}, 0, { NULL }, "Glow Mapping" },
|
||||
{ SDR_FLAG_SPEC_MAP, 1, {"sSpecmap"}, 0, { NULL }, "Specular Mapping" },
|
||||
{ SDR_FLAG_NORMAL_MAP, 1, {"sNormalmap"}, 0, { NULL }, "Normal Mapping" },
|
||||
{ SDR_FLAG_HEIGHT_MAP, 1, {"sHeightmap"}, 0, { NULL }, "Parallax Mapping" },
|
||||
{ SDR_FLAG_ENV_MAP, 3, {"sEnvmap", "alpha_spec", "envMatrix"}, 0, { NULL }, "Environment Mapping" },
|
||||
{ SDR_FLAG_ANIMATED, 5, {"sFramebuffer", "effect_num", "anim_timer", "vpwidth", "vpheight"}, 0, { NULL }, "Animated Effects" },
|
||||
{ SDR_FLAG_MISC_MAP, 1, {"sMiscmap"}, 0, { NULL }, "Utility mapping" },
|
||||
{ SDR_FLAG_TEAMCOLOR, 2, {"stripe_color", "base_color"}, 0, { NULL }, "Team Colors" },
|
||||
{ SDR_FLAG_THRUSTER, 1, {"thruster_scale"}, 0, { NULL }, "Thruster scaling" }
|
||||
};
|
||||
static opengl_shader_type_t GL_shader_types[] = {
|
||||
{ SDR_TYPE_MODEL, "main-v.sdr", "main-f.sdr", "main-g.sdr", {GL_TRIANGLES, GL_TRIANGLE_STRIP, 3},
|
||||
0, {}, 0, {}, "Model Rendering" },
|
||||
|
||||
static const int Main_shader_flag_references = sizeof(GL_Uniform_Reference_Main) / sizeof(opengl_shader_uniform_reference_t);
|
||||
{ SDR_TYPE_EFFECT_PARTICLE, "effect-v.sdr", "effect-particle-f.sdr", "effect-screen-g.sdr", {GL_POINTS, GL_TRIANGLE_STRIP, 4},
|
||||
7, { "baseMap", "depthMap", "window_width", "window_height", "nearZ", "farZ", "linear_depth" }, 1, {"radius"}, "Particle Effects" },
|
||||
|
||||
{ SDR_TYPE_EFFECT_DISTORTION, "effect-distort-v.sdr", "effect-distort-f.sdr", 0, { 0, 0, 0 },
|
||||
6, { "baseMap", "window_width", "window_height", "distMap", "frameBuffer", "use_offset" }, 1, { "radius" }, "Distortion Effects" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_MAIN, "post-v.sdr", "post-f.sdr", 0, {0, 0, 0},
|
||||
5, { "tex", "depth_tex", "timer", "bloomed", "bloom_intensity" }, 0, { NULL }, "Post Processing" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_BLUR, "post-v.sdr", "blur-f.sdr", 0, {0, 0, 0},
|
||||
2, { "tex", "bsize", "debug" }, 0, { NULL }, "Gaussian Blur" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_BRIGHTPASS, "post-v.sdr", "brightpass-f.sdr", 0, { 0, 0, 0 },
|
||||
1, { "tex" }, 0, { NULL }, "Bloom Brightpass" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_FXAA, "fxaa-v.sdr", "fxaa-f.sdr", 0, {0, 0, 0},
|
||||
3, { "tex0", "rt_w", "rt_h" }, 0, { NULL }, "FXAA" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_FXAA_PREPASS, "post-v.sdr", "fxaapre-f.sdr", 0, {0, 0, 0},
|
||||
1, { "tex" }, 0, { NULL }, "FXAA Prepass" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_LIGHTSHAFTS, "post-v.sdr", "ls-f.sdr", 0, {0, 0, 0},
|
||||
8, { "scene", "cockpit", "sun_pos", "weight", "intensity", "falloff", "density", "cp_intensity" }, 0, { NULL }, "Lightshafts" },
|
||||
|
||||
{ SDR_TYPE_DEFERRED_LIGHTING, "deferred-v.sdr", "deferred-f.sdr", 0, { 0, 0, 0 },
|
||||
16, { "scale", "ColorBuffer", "NormalBuffer", "PositionBuffer", "SpecBuffer", "invScreenWidth", "invScreenHeight", "lightType", "lightRadius", "diffuseLightColor",
|
||||
"specLightColor", "dualCone", "coneDir", "coneAngle", "coneInnerAngle", "specFactor" }, 0, { NULL }, "Deferred Lighting" },
|
||||
|
||||
{ SDR_TYPE_DEFERRED_CLEAR, "deferred-clear-v.sdr", "deferred-clear-f.sdr", 0, {0, 0, 0},
|
||||
0, { NULL }, 0, { NULL }, "Clear Deferred Lighting Buffer" },
|
||||
|
||||
{ SDR_TYPE_VIDEO_PROCESS, "video-v.sdr", "video-f.sdr", 0, {0, 0, 0},
|
||||
3, { "ytex", "utex", "vtex" }, 0, { NULL }, "Video Playback" }
|
||||
};
|
||||
|
||||
/**
|
||||
* Static lookup referene for particle shader uniforms
|
||||
* Static lookup reference for shader variant uniforms
|
||||
* When adding a new shader variant for a shader, list all associated uniforms and attributes here
|
||||
*/
|
||||
static opengl_shader_uniform_reference_t GL_Uniform_Reference_Particle[] = {
|
||||
{ (SDR_FLAG_SOFT_QUAD | SDR_FLAG_DISTORTION), 6, {"baseMap", "window_width", "window_height", "distMap", "frameBuffer", "use_offset"}, 1, { "offset_in" }, "Distorted Particles" },
|
||||
{ (SDR_FLAG_SOFT_QUAD), 6, {"baseMap", "depthMap", "window_width", "window_height", "nearZ", "farZ"}, 1, { "radius_in" }, "Depth-blended Particles" }
|
||||
static opengl_shader_variant_t GL_shader_variants[] = {
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_LIGHT, "FLAG_LIGHT",
|
||||
2, { "n_lights", "light_factor" }, 0, { NULL },
|
||||
"Lighting" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_FOG, "FLAG_FOG",
|
||||
0, { NULL }, 0, { NULL },
|
||||
"Fog Effect" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_DIFFUSE_MAP, "FLAG_DIFFUSE_MAP",
|
||||
4, { "sBasemap", "desaturate", "desaturate_clr", "blend_alpha" }, 0, { NULL },
|
||||
"Diffuse Mapping" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_GLOW_MAP, "FLAG_GLOW_MAP",
|
||||
1, { "sGlowmap" }, 0, { NULL },
|
||||
"Glow Mapping" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_SPEC_MAP, "FLAG_SPEC_MAP",
|
||||
1, { "sSpecmap" }, 0, { NULL },
|
||||
"Specular Mapping" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_NORMAL_MAP, "FLAG_NORMAL_MAP",
|
||||
1, { "sNormalmap" }, 0, { NULL },
|
||||
"Normal Mapping" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_HEIGHT_MAP, "FLAG_HEIGHT_MAP",
|
||||
1, { "sHeightmap" }, 0, { NULL },
|
||||
"Parallax Mapping" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_ENV_MAP, "FLAG_ENV_MAP",
|
||||
3, { "sEnvmap", "alpha_spec", "envMatrix" }, 0, { NULL },
|
||||
"Environment Mapping" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_ANIMATED, "FLAG_ANIMATED",
|
||||
5, { "sFramebuffer", "effect_num", "anim_timer", "vpwidth", "vpheight" }, 0, { NULL },
|
||||
"Animated Effects" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_MISC_MAP, "FLAG_MISC_MAP",
|
||||
1, { "sMiscmap" }, 0, { NULL },
|
||||
"Utility mapping" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_TEAMCOLOR, "FLAG_TEAMCOLOR",
|
||||
2, { "stripe_color", "base_color" }, 0, { NULL },
|
||||
"Team Colors" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_DEFERRED, "FLAG_DEFERRED",
|
||||
0, { NULL }, 0, { NULL },
|
||||
"Deferred lighting" },
|
||||
|
||||
{ SDR_TYPE_MODEL, true, SDR_FLAG_MODEL_SHADOW_MAP, "FLAG_SHADOW_MAP",
|
||||
1, { "shadow_proj_matrix" }, 0, { NULL },
|
||||
"Shadow Mapping" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_SHADOWS, "FLAG_SHADOWS",
|
||||
8, { "shadow_map", "shadow_mv_matrix", "shadow_proj_matrix", "model_matrix", "veryneardist", "neardist", "middist", "fardist" }, 0, { NULL },
|
||||
"Shadows" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_THRUSTER, "FLAG_THRUSTER",
|
||||
1, { "thruster_scale" }, 0, { NULL },
|
||||
"Thruster scaling" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_TRANSFORM, "FLAG_TRANSFORM",
|
||||
2, { "transform_tex", "buffer_matrix_offset" }, 1, { "model_id" },
|
||||
"Submodel Transforms" },
|
||||
|
||||
{ SDR_TYPE_MODEL, false, SDR_FLAG_MODEL_CLIP, "FLAG_CLIP",
|
||||
4, { "use_clip_plane", "world_matrix", "clip_normal", "clip_position" }, 0, { NULL },
|
||||
"Clip Plane" },
|
||||
|
||||
{ SDR_TYPE_EFFECT_PARTICLE, true, SDR_FLAG_PARTICLE_POINT_GEN, "FLAG_EFFECT_GEOMETRY",
|
||||
0, { NULL }, 1, { "uvec" },
|
||||
"Geometry shader point-based particles" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_BLUR, false, SDR_FLAG_BLUR_HORIZONTAL, "PASS_0",
|
||||
0, { NULL }, 0, { NULL },
|
||||
"Horizontal blur pass" },
|
||||
|
||||
{ SDR_TYPE_POST_PROCESS_BLUR, false, SDR_FLAG_BLUR_VERTICAL, "PASS_1",
|
||||
0, { NULL }, 0, { NULL },
|
||||
"Vertical blur pass" }
|
||||
};
|
||||
|
||||
static const int Particle_shader_flag_references = sizeof(GL_Uniform_Reference_Particle) / sizeof(opengl_shader_uniform_reference_t);
|
||||
static const int GL_num_shader_variants = sizeof(GL_shader_variants) / sizeof(opengl_shader_variant_t);
|
||||
|
||||
opengl_shader_t *Current_shader = NULL;
|
||||
|
||||
|
||||
void opengl_shader_check_info_log(GLhandleARB shader_object);
|
||||
|
||||
/**
|
||||
@@ -86,7 +185,7 @@ void opengl_shader_set_current(opengl_shader_t *shader_obj)
|
||||
if(!Current_shader || (Current_shader->program_id != shader_obj->program_id)) {
|
||||
Current_shader = shader_obj;
|
||||
vglUseProgramObjectARB(Current_shader->program_id);
|
||||
|
||||
GL_state.Uniform.reset();
|
||||
#ifndef NDEBUG
|
||||
if ( opengl_check_for_errors("shader_set_current()") ) {
|
||||
vglValidateProgramARB(Current_shader->program_id);
|
||||
@@ -114,13 +213,22 @@ void opengl_shader_set_current(opengl_shader_t *shader_obj)
|
||||
}
|
||||
}
|
||||
|
||||
void opengl_shader_set_current(int handle)
|
||||
{
|
||||
Assert(handle >= 0);
|
||||
Assert(handle < (int)GL_shader.size());
|
||||
|
||||
opengl_shader_set_current(&GL_shader[handle]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a set of flags, determine whether a shader with these flags exists within the GL_shader vector. If no shader with the requested flags exists, attempt to compile one.
|
||||
*
|
||||
* @param shader shader_type variable, a reference to the shader program needed
|
||||
* @param flags Integer variable, holding a combination of SDR_* flags
|
||||
* @return Index into GL_shader, referencing a valid shader, or -1 if shader compilation failed
|
||||
*/
|
||||
int gr_opengl_maybe_create_shader(int flags)
|
||||
int gr_opengl_maybe_create_shader(shader_type shader, unsigned int flags)
|
||||
{
|
||||
if (Use_GLSL < 2)
|
||||
return -1;
|
||||
@@ -129,18 +237,32 @@ int gr_opengl_maybe_create_shader(int flags)
|
||||
size_t max = GL_shader.size();
|
||||
|
||||
for (idx = 0; idx < max; idx++) {
|
||||
if (GL_shader[idx].flags == flags) {
|
||||
if (GL_shader[idx].shader == shader && GL_shader[idx].flags == flags) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are here, it means we need to compile a new shader
|
||||
opengl_compile_main_shader(flags);
|
||||
if (GL_shader.back().flags == flags)
|
||||
return (int)GL_shader.size() - 1;
|
||||
return opengl_compile_shader(shader, flags);
|
||||
}
|
||||
|
||||
// If even that has failed, bail
|
||||
return -1;
|
||||
void opengl_delete_shader(int sdr_handle)
|
||||
{
|
||||
Assert(sdr_handle >= 0);
|
||||
Assert(sdr_handle < (int)GL_shader.size());
|
||||
|
||||
if (GL_shader[sdr_handle].program_id) {
|
||||
vglDeleteObjectARB(GL_shader[sdr_handle].program_id);
|
||||
GL_shader[sdr_handle].program_id = 0;
|
||||
}
|
||||
|
||||
GL_shader[sdr_handle].flags = 0;
|
||||
GL_shader[sdr_handle].flags2 = 0;
|
||||
GL_shader[sdr_handle].shader = NUM_SHADER_TYPES;
|
||||
|
||||
GL_shader[sdr_handle].uniforms.clear();
|
||||
GL_shader[sdr_handle].attributes.clear();
|
||||
GL_shader[sdr_handle].uniform_blocks.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,6 +283,8 @@ void opengl_shader_shutdown()
|
||||
}
|
||||
|
||||
GL_shader[i].uniforms.clear();
|
||||
GL_shader[i].attributes.clear();
|
||||
GL_shader[i].uniform_blocks.clear();
|
||||
}
|
||||
|
||||
GL_shader.clear();
|
||||
@@ -176,90 +300,62 @@ void opengl_shader_shutdown()
|
||||
* This function will also create a list of preprocessor defines for the GLSL compiler based on the shader flags
|
||||
* and the supported GLSL version as reported by the GPU driver.
|
||||
*
|
||||
* @param shader shader_type enum defined with which shader we're loading
|
||||
* @param filename C-string holding the filename (with extension) of the shader file
|
||||
* @param flags integer variable holding a combination of SDR_* flags
|
||||
* @return C-string holding the complete shader source code
|
||||
*/
|
||||
static char *opengl_load_shader(char *filename, int flags)
|
||||
static char *opengl_load_shader(shader_type type_id, char *filename, int flags)
|
||||
{
|
||||
SCP_string sflags;
|
||||
|
||||
#ifdef __APPLE__
|
||||
sflags += "#version 120\n";
|
||||
#endif
|
||||
|
||||
if (Use_GLSL >= 4) {
|
||||
sflags += "#define SHADER_MODEL 4\n";
|
||||
} else if (Use_GLSL == 3) {
|
||||
}
|
||||
else if (Use_GLSL == 3) {
|
||||
sflags += "#define SHADER_MODEL 3\n";
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
sflags += "#define SHADER_MODEL 2\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_DIFFUSE_MAP) {
|
||||
sflags += "#define FLAG_DIFFUSE_MAP\n";
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
sflags += "#define APPLE\n";
|
||||
#endif
|
||||
|
||||
if (flags & SDR_FLAG_ENV_MAP) {
|
||||
sflags += "#define FLAG_ENV_MAP\n";
|
||||
}
|
||||
if (type_id == SDR_TYPE_POST_PROCESS_MAIN || type_id == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS || type_id == SDR_TYPE_POST_PROCESS_FXAA) {
|
||||
// ignore looking for variants. main post process, lightshafts, and FXAA shaders need special headers to be hacked in
|
||||
opengl_post_load_shader(sflags, type_id, flags);
|
||||
} else {
|
||||
for (int i = 0; i < GL_num_shader_variants; ++i) {
|
||||
opengl_shader_variant_t &variant = GL_shader_variants[i];
|
||||
|
||||
if (flags & SDR_FLAG_FOG) {
|
||||
sflags += "#define FLAG_FOG\n";
|
||||
if (type_id == variant.type_id && flags & variant.flag) {
|
||||
sflags += "#define " + variant.flag_text + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_GLOW_MAP) {
|
||||
sflags += "#define FLAG_GLOW_MAP\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_HEIGHT_MAP) {
|
||||
sflags += "#define FLAG_HEIGHT_MAP\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_LIGHT) {
|
||||
sflags += "#define FLAG_LIGHT\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_NORMAL_MAP) {
|
||||
sflags += "#define FLAG_NORMAL_MAP\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_SPEC_MAP) {
|
||||
sflags += "#define FLAG_SPEC_MAP\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_ANIMATED) {
|
||||
sflags += "#define FLAG_ANIMATED\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_DISTORTION) {
|
||||
sflags += "#define FLAG_DISTORTION\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_MISC_MAP) {
|
||||
sflags += "#define FLAG_MISC_MAP\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_TEAMCOLOR) {
|
||||
sflags += "#define FLAG_TEAMCOLOR\n";
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_THRUSTER) {
|
||||
sflags += "#define FLAG_THRUSTER\n";
|
||||
}
|
||||
|
||||
|
||||
const char *shader_flags = sflags.c_str();
|
||||
int flags_len = strlen(shader_flags);
|
||||
|
||||
if (Enable_external_shaders) {
|
||||
CFILE *cf_shader = cfopen(filename, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS);
|
||||
|
||||
|
||||
if (cf_shader != NULL) {
|
||||
int len = cfilelength(cf_shader);
|
||||
char *shader = (char*) vm_malloc(len + flags_len + 1);
|
||||
char *shader = (char*)vm_malloc(len + flags_len + 1);
|
||||
|
||||
strcpy(shader, shader_flags);
|
||||
memset(shader + flags_len, 0, len + 1);
|
||||
cfread(shader + flags_len, len + 1, 1, cf_shader);
|
||||
cfclose(cf_shader);
|
||||
|
||||
return shader;
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +363,7 @@ static char *opengl_load_shader(char *filename, int flags)
|
||||
mprintf((" Loading built-in default shader for: %s\n", filename));
|
||||
char* def_shader = defaults_get_file(filename);
|
||||
size_t len = strlen(def_shader);
|
||||
char *shader = (char*) vm_malloc(len + flags_len + 1);
|
||||
char *shader = (char*)vm_malloc(len + flags_len + 1);
|
||||
|
||||
strcpy(shader, shader_flags);
|
||||
strcat(shader, def_shader);
|
||||
@@ -278,101 +374,135 @@ static char *opengl_load_shader(char *filename, int flags)
|
||||
/**
|
||||
* Compiles a new shader, and creates an opengl_shader_t that will be put into the GL_shader vector
|
||||
* if compilation is successful.
|
||||
* This function is used for main (i.e. model rendering) and particle shaders, post processing shaders use their own infrastructure
|
||||
*
|
||||
* @param sdr Identifier defined with the program we wish to compile
|
||||
* @param flags Combination of SDR_* flags
|
||||
*/
|
||||
void opengl_compile_main_shader(int flags) {
|
||||
char *vert = NULL, *frag = NULL;
|
||||
|
||||
mprintf(("Compiling new shader:\n"));
|
||||
int opengl_compile_shader(shader_type sdr, uint flags)
|
||||
{
|
||||
int sdr_index = -1;
|
||||
int empty_idx;
|
||||
char *vert = NULL, *frag = NULL, *geom = NULL;
|
||||
|
||||
bool in_error = false;
|
||||
opengl_shader_t new_shader;
|
||||
|
||||
// choose appropriate files
|
||||
char vert_name[NAME_LENGTH];
|
||||
char frag_name[NAME_LENGTH];
|
||||
Assert(sdr < NUM_SHADER_TYPES);
|
||||
|
||||
if (flags & SDR_FLAG_SOFT_QUAD) {
|
||||
strcpy_s( vert_name, "soft-v.sdr");
|
||||
strcpy_s( frag_name, "soft-f.sdr");
|
||||
} else {
|
||||
strcpy_s( vert_name, "main-v.sdr");
|
||||
strcpy_s( frag_name, "main-f.sdr");
|
||||
opengl_shader_type_t *sdr_info = &GL_shader_types[sdr];
|
||||
|
||||
mprintf(("Compiling new shader:\n"));
|
||||
mprintf((" %s\n", sdr_info->description));
|
||||
|
||||
// figure out if the variant requested needs a geometry shader
|
||||
bool use_geo_sdr = false;
|
||||
|
||||
// do we even have a geometry shader?
|
||||
if ( sdr_info->geo != NULL ) {
|
||||
for (int i = 0; i < GL_num_shader_variants; ++i) {
|
||||
opengl_shader_variant_t *variant = &GL_shader_variants[i];
|
||||
|
||||
if (variant->type_id == sdr && flags & variant->flag && variant->use_geometry_sdr) {
|
||||
use_geo_sdr = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// read vertex shader
|
||||
if ( (vert = opengl_load_shader(vert_name, flags)) == NULL ) {
|
||||
if ((vert = opengl_load_shader(sdr_info->type_id, sdr_info->vert, flags)) == NULL) {
|
||||
in_error = true;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
|
||||
// read fragment shader
|
||||
if ( (frag = opengl_load_shader(frag_name, flags)) == NULL ) {
|
||||
if ((frag = opengl_load_shader(sdr_info->type_id, sdr_info->frag, flags)) == NULL) {
|
||||
in_error = true;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Verify( vert != NULL );
|
||||
Verify( frag != NULL );
|
||||
if ( use_geo_sdr ) {
|
||||
if (!Is_Extension_Enabled(OGL_EXT_GEOMETRY_SHADER4)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
new_shader.program_id = opengl_shader_create(vert, frag);
|
||||
// read geometry shader
|
||||
if ((geom = opengl_load_shader(sdr_info->type_id, sdr_info->geo, flags)) == NULL) {
|
||||
in_error = true;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if ( !new_shader.program_id ) {
|
||||
Current_geo_sdr_params = &sdr_info->geo_sdr_info;
|
||||
}
|
||||
|
||||
Verify(vert != NULL);
|
||||
Verify(frag != NULL);
|
||||
|
||||
new_shader.program_id = opengl_shader_create(vert, frag, geom);
|
||||
|
||||
if (!new_shader.program_id) {
|
||||
in_error = true;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
new_shader.shader = sdr_info->type_id;
|
||||
new_shader.flags = flags;
|
||||
|
||||
opengl_shader_set_current( &new_shader );
|
||||
|
||||
mprintf(("Shader features:\n"));
|
||||
opengl_shader_set_current(&new_shader);
|
||||
|
||||
//Init all the uniforms
|
||||
if (new_shader.flags & SDR_FLAG_SOFT_QUAD) {
|
||||
for (int j = 0; j < Particle_shader_flag_references; j++) {
|
||||
if (new_shader.flags == GL_Uniform_Reference_Particle[j].flag) {
|
||||
int k;
|
||||
// initialize uniforms and attributes
|
||||
for ( int i = 0; i < sdr_info->num_uniforms; ++i ) {
|
||||
opengl_shader_init_uniform( sdr_info->uniforms[i] );
|
||||
}
|
||||
|
||||
// Equality check needed because the combination of SDR_FLAG_SOFT_QUAD and SDR_FLAG_DISTORTION define something very different
|
||||
// than just SDR_FLAG_SOFT_QUAD alone
|
||||
for (k = 0; k < GL_Uniform_Reference_Particle[j].num_uniforms; k++) {
|
||||
opengl_shader_init_uniform( GL_Uniform_Reference_Particle[j].uniforms[k] );
|
||||
}
|
||||
for (int i = 0; i < sdr_info->num_attributes; ++i) {
|
||||
opengl_shader_init_attribute(sdr_info->attributes[i]);
|
||||
}
|
||||
|
||||
for (k = 0; k < GL_Uniform_Reference_Particle[j].num_attributes; k++) {
|
||||
opengl_shader_init_attribute( GL_Uniform_Reference_Particle[j].attributes[k] );
|
||||
}
|
||||
// if this shader is POST_PROCESS_MAIN, hack in the user-defined flags
|
||||
if ( sdr_info->type_id == SDR_TYPE_POST_PROCESS_MAIN ) {
|
||||
opengl_post_init_uniforms(flags);
|
||||
}
|
||||
|
||||
mprintf((" %s\n", GL_Uniform_Reference_Particle[j].name));
|
||||
mprintf(("Shader Variant Features:\n"));
|
||||
|
||||
// initialize all uniforms and attributes that are specific to this variant
|
||||
for ( int i = 0; i < GL_num_shader_variants; ++i ) {
|
||||
opengl_shader_variant_t &variant = GL_shader_variants[i];
|
||||
|
||||
if ( sdr_info->type_id == variant.type_id && variant.flag & flags ) {
|
||||
for (int j = 0; j < variant.num_uniforms; ++j) {
|
||||
opengl_shader_init_uniform(variant.uniforms[j]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < Main_shader_flag_references; j++) {
|
||||
if (new_shader.flags & GL_Uniform_Reference_Main[j].flag) {
|
||||
if (GL_Uniform_Reference_Main[j].num_uniforms > 0) {
|
||||
for (int k = 0; k < GL_Uniform_Reference_Main[j].num_uniforms; k++) {
|
||||
opengl_shader_init_uniform( GL_Uniform_Reference_Main[j].uniforms[k] );
|
||||
}
|
||||
}
|
||||
|
||||
if (GL_Uniform_Reference_Main[j].num_attributes > 0) {
|
||||
for (int k = 0; k < GL_Uniform_Reference_Main[j].num_attributes; k++) {
|
||||
opengl_shader_init_attribute( GL_Uniform_Reference_Main[j].attributes[k] );
|
||||
}
|
||||
}
|
||||
|
||||
mprintf((" %s\n", GL_Uniform_Reference_Main[j].name));
|
||||
for (int j = 0; j < variant.num_attributes; ++j) {
|
||||
opengl_shader_init_attribute(variant.attributes[j]);
|
||||
}
|
||||
|
||||
mprintf((" %s\n", variant.description));
|
||||
}
|
||||
}
|
||||
|
||||
opengl_shader_set_current();
|
||||
|
||||
// add it to our list of embedded shaders
|
||||
GL_shader.push_back( new_shader );
|
||||
// see if we have empty shader slots
|
||||
empty_idx = -1;
|
||||
for ( int i = 0; i < (int)GL_shader.size(); ++i ) {
|
||||
if ( GL_shader[i].shader == NUM_SHADER_TYPES ) {
|
||||
empty_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// then insert it at an empty slot or at the end
|
||||
if ( empty_idx >= 0 ) {
|
||||
GL_shader[empty_idx] = new_shader;
|
||||
sdr_index = empty_idx;
|
||||
} else {
|
||||
sdr_index = GL_shader.size();
|
||||
GL_shader.push_back(new_shader);
|
||||
}
|
||||
|
||||
Done:
|
||||
if (vert != NULL) {
|
||||
@@ -385,43 +515,12 @@ Done:
|
||||
frag = NULL;
|
||||
}
|
||||
|
||||
if (in_error) {
|
||||
// shut off relevant usage things ...
|
||||
bool dealt_with = false;
|
||||
|
||||
if (flags & SDR_FLAG_HEIGHT_MAP) {
|
||||
mprintf((" Shader in_error! Disabling height maps!\n"));
|
||||
Cmdline_height = 0;
|
||||
dealt_with = true;
|
||||
}
|
||||
|
||||
if (flags & SDR_FLAG_NORMAL_MAP) {
|
||||
mprintf((" Shader in_error! Disabling normal maps and height maps!\n"));
|
||||
Cmdline_height = 0;
|
||||
Cmdline_normal = 0;
|
||||
dealt_with = true;
|
||||
}
|
||||
|
||||
if (!dealt_with) {
|
||||
if (flags == 0) {
|
||||
mprintf((" Shader in_error! Disabling GLSL!\n"));
|
||||
|
||||
Use_GLSL = 0;
|
||||
Cmdline_height = 0;
|
||||
Cmdline_normal = 0;
|
||||
|
||||
GL_shader.clear();
|
||||
} else {
|
||||
// We died on a lighting shader, probably due to instruction count.
|
||||
// Drop down to a special var that will use fixed-function rendering
|
||||
// but still allow for post-processing to work
|
||||
mprintf((" Shader in_error! Disabling GLSL model rendering!\n"));
|
||||
Use_GLSL = 1;
|
||||
Cmdline_height = 0;
|
||||
Cmdline_normal = 0;
|
||||
}
|
||||
}
|
||||
if (geom != NULL ) {
|
||||
vm_free(geom);
|
||||
geom = NULL;
|
||||
}
|
||||
|
||||
return sdr_index;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -456,10 +555,13 @@ void opengl_shader_init()
|
||||
// Reserve 32 shader slots. This should cover most use cases in real life.
|
||||
GL_shader.reserve(32);
|
||||
|
||||
// Compile the particle shaders, since these are most definitely going to be used
|
||||
opengl_compile_main_shader(SDR_FLAG_SOFT_QUAD);
|
||||
opengl_compile_main_shader(SDR_FLAG_SOFT_QUAD | SDR_FLAG_DISTORTION);
|
||||
// compile effect shaders
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_PARTICLE, 0);
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_PARTICLE, SDR_FLAG_PARTICLE_POINT_GEN);
|
||||
gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_DISTORTION, 0);
|
||||
|
||||
// compile deferred lighting shaders
|
||||
opengl_shader_compile_deferred_light_shader();
|
||||
mprintf(("\n"));
|
||||
}
|
||||
|
||||
@@ -506,7 +608,7 @@ GLhandleARB opengl_shader_compile_object(const GLcharARB *shader_source, GLenum
|
||||
// we failed, bail out now...
|
||||
if (status == 0) {
|
||||
// basic error check
|
||||
mprintf(("%s shader failed to compile:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : "Fragment", GLshader_info_log));
|
||||
mprintf(("%s shader failed to compile:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : ((shader_type == GL_GEOMETRY_SHADER_EXT) ? "Geometry" : "Fragment"), GLshader_info_log));
|
||||
|
||||
// this really shouldn't exist, but just in case
|
||||
if (shader_object) {
|
||||
@@ -518,7 +620,7 @@ GLhandleARB opengl_shader_compile_object(const GLcharARB *shader_source, GLenum
|
||||
|
||||
// we succeeded, maybe output warnings too
|
||||
if (strlen(GLshader_info_log) > 5) {
|
||||
nprintf(("SHADER-DEBUG", "%s shader compiled with warnings:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : "Fragment", GLshader_info_log));
|
||||
nprintf(("SHADER-DEBUG", "%s shader compiled with warnings:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : ((shader_type == GL_GEOMETRY_SHADER_EXT) ? "Geometry" : "Fragment"), GLshader_info_log));
|
||||
}
|
||||
|
||||
return shader_object;
|
||||
@@ -532,7 +634,7 @@ GLhandleARB opengl_shader_compile_object(const GLcharARB *shader_source, GLenum
|
||||
* @param fragment_object Compiled fragment shader object
|
||||
* @return Shader executable
|
||||
*/
|
||||
GLhandleARB opengl_shader_link_object(GLhandleARB vertex_object, GLhandleARB fragment_object)
|
||||
GLhandleARB opengl_shader_link_object(GLhandleARB vertex_object, GLhandleARB fragment_object, GLhandleARB geometry_object)
|
||||
{
|
||||
GLhandleARB shader_object = 0;
|
||||
GLint status = 0;
|
||||
@@ -546,7 +648,22 @@ GLhandleARB opengl_shader_link_object(GLhandleARB vertex_object, GLhandleARB fra
|
||||
if (fragment_object) {
|
||||
vglAttachObjectARB(shader_object, fragment_object);
|
||||
}
|
||||
|
||||
|
||||
if (geometry_object) {
|
||||
vglAttachObjectARB(shader_object, geometry_object);
|
||||
|
||||
if ( Current_geo_sdr_params != NULL) {
|
||||
#ifdef __APPLE__
|
||||
vglProgramParameteriEXT((long)shader_object, GL_GEOMETRY_INPUT_TYPE_EXT, Current_geo_sdr_params->input_type);
|
||||
vglProgramParameteriEXT((long)shader_object, GL_GEOMETRY_OUTPUT_TYPE_EXT, Current_geo_sdr_params->output_type);
|
||||
vglProgramParameteriEXT((long)shader_object, GL_GEOMETRY_VERTICES_OUT_EXT, Current_geo_sdr_params->vertices_out);
|
||||
#else
|
||||
vglProgramParameteriEXT((GLuint)shader_object, GL_GEOMETRY_INPUT_TYPE_EXT, Current_geo_sdr_params->input_type);
|
||||
vglProgramParameteriEXT((GLuint)shader_object, GL_GEOMETRY_OUTPUT_TYPE_EXT, Current_geo_sdr_params->output_type);
|
||||
vglProgramParameteriEXT((GLuint)shader_object, GL_GEOMETRY_VERTICES_OUT_EXT, Current_geo_sdr_params->vertices_out);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
vglLinkProgramARB(shader_object);
|
||||
|
||||
// check if the link was successful
|
||||
@@ -580,10 +697,11 @@ GLhandleARB opengl_shader_link_object(GLhandleARB vertex_object, GLhandleARB fra
|
||||
* @param fs Fragment shader source code
|
||||
* @return Internal ID of the compiled and linked shader as generated by OpenGL
|
||||
*/
|
||||
GLhandleARB opengl_shader_create(const char *vs, const char *fs)
|
||||
GLhandleARB opengl_shader_create(const char *vs, const char *fs, const char *gs)
|
||||
{
|
||||
GLhandleARB vs_o = 0;
|
||||
GLhandleARB fs_o = 0;
|
||||
GLhandleARB gs_o = 0;
|
||||
GLhandleARB program = 0;
|
||||
|
||||
if (vs) {
|
||||
@@ -604,7 +722,16 @@ GLhandleARB opengl_shader_create(const char *vs, const char *fs)
|
||||
}
|
||||
}
|
||||
|
||||
program = opengl_shader_link_object(vs_o, fs_o);
|
||||
if (gs) {
|
||||
gs_o = opengl_shader_compile_object( (const GLcharARB*)gs, GL_GEOMETRY_SHADER_EXT );
|
||||
|
||||
if ( !gs_o ) {
|
||||
mprintf(("ERROR! Unable to create fragment shader!\n"));
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
program = opengl_shader_link_object(vs_o, fs_o, gs_o);
|
||||
|
||||
if ( !program ) {
|
||||
mprintf(("ERROR! Unable to create shader program!\n"));
|
||||
@@ -619,6 +746,10 @@ Done:
|
||||
vglDeleteObjectARB(fs_o);
|
||||
}
|
||||
|
||||
if (gs_o) {
|
||||
vglDeleteObjectARB(gs_o);
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
@@ -721,15 +852,68 @@ GLint opengl_shader_get_uniform(const char *uniform_text)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a shader uniform. Requires that the Current_shader global variable is valid.
|
||||
*
|
||||
* @param uniform_text Name of the uniform to be initialized
|
||||
*/
|
||||
void opengl_shader_init_uniform_block(const char *uniform_text)
|
||||
{
|
||||
opengl_shader_uniform_t new_uniform_block;
|
||||
|
||||
if ( (Current_shader == NULL) || (uniform_text == NULL) ) {
|
||||
Int3();
|
||||
return;
|
||||
}
|
||||
|
||||
new_uniform_block.text_id = uniform_text;
|
||||
#ifdef __APPLE__
|
||||
new_uniform_block.location = vglGetUniformBlockIndexARB((long)Current_shader->program_id, uniform_text);
|
||||
#else
|
||||
new_uniform_block.location = vglGetUniformBlockIndexARB(Current_shader->program_id, uniform_text);
|
||||
#endif
|
||||
if (new_uniform_block.location < 0) {
|
||||
nprintf(("SHADER-DEBUG", "WARNING: Unable to get shader uniform block location for \"%s\"!\n", uniform_text));
|
||||
return;
|
||||
}
|
||||
|
||||
Current_shader->uniform_blocks.push_back( new_uniform_block );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internal OpenGL location for a given uniform. Requires that the Current_shader global variable is valid
|
||||
*
|
||||
* @param uniform_text Name of the uniform
|
||||
* @return Internal OpenGL location for the uniform
|
||||
*/
|
||||
GLint opengl_shader_get_uniform_block(const char *uniform_text)
|
||||
{
|
||||
if ( (Current_shader == NULL) || (uniform_text == NULL) ) {
|
||||
Int3();
|
||||
return -1;
|
||||
}
|
||||
|
||||
SCP_vector<opengl_shader_uniform_t>::iterator uniform_block;
|
||||
|
||||
for (uniform_block = Current_shader->uniform_blocks.begin(); uniform_block != Current_shader->uniform_blocks.end(); ++uniform_block) {
|
||||
if ( !uniform_block->text_id.compare(uniform_text) ) {
|
||||
return uniform_block->location;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently active animated effect.
|
||||
*
|
||||
* @param effect Effect ID, needs to be implemented and checked for in the shader
|
||||
* @param timer Timer value to be passed to the shader
|
||||
*/
|
||||
void opengl_shader_set_animated_effect(int effect)
|
||||
void gr_opengl_shader_set_animated_effect(int effect, float timer)
|
||||
{
|
||||
Assert(effect > -1);
|
||||
Effect_num = effect;
|
||||
GL_anim_effect_num = effect;
|
||||
GL_anim_timer = timer;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -739,17 +923,7 @@ void opengl_shader_set_animated_effect(int effect)
|
||||
*/
|
||||
int opengl_shader_get_animated_effect()
|
||||
{
|
||||
return Effect_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timer for animated effects.
|
||||
*
|
||||
* @param timer Timer value to be passed to the shader
|
||||
*/
|
||||
void opengl_shader_set_animated_timer(float timer)
|
||||
{
|
||||
Anim_timer = timer;
|
||||
return GL_anim_effect_num;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -757,5 +931,41 @@ void opengl_shader_set_animated_timer(float timer)
|
||||
*/
|
||||
float opengl_shader_get_animated_timer()
|
||||
{
|
||||
return Anim_timer;
|
||||
return GL_anim_timer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the deferred light shader.
|
||||
*/
|
||||
void opengl_shader_compile_deferred_light_shader()
|
||||
{
|
||||
bool in_error = false;
|
||||
|
||||
int sdr_handle = gr_opengl_maybe_create_shader(SDR_TYPE_DEFERRED_LIGHTING, 0);
|
||||
|
||||
if ( sdr_handle >= 0 ) {
|
||||
opengl_shader_set_current(sdr_handle);
|
||||
|
||||
GL_state.Uniform.setUniformi("ColorBuffer", 0);
|
||||
GL_state.Uniform.setUniformi("NormalBuffer", 1);
|
||||
GL_state.Uniform.setUniformi("PositionBuffer", 2);
|
||||
GL_state.Uniform.setUniformi("SpecBuffer", 3);
|
||||
GL_state.Uniform.setUniformf("invScreenWidth", 1.0f / gr_screen.max_w);
|
||||
GL_state.Uniform.setUniformf("invScreenHeight", 1.0f / gr_screen.max_h);
|
||||
GL_state.Uniform.setUniformf("specFactor", Cmdline_ogl_spec);
|
||||
} else {
|
||||
opengl_shader_set_current();
|
||||
mprintf(("Failed to compile deferred lighting shader!\n"));
|
||||
in_error = true;
|
||||
}
|
||||
|
||||
if ( gr_opengl_maybe_create_shader(SDR_TYPE_DEFERRED_CLEAR, 0) < 0 ) {
|
||||
mprintf(("Failed to compile deferred lighting buffer clear shader!\n"));
|
||||
in_error = true;
|
||||
}
|
||||
|
||||
if ( in_error ) {
|
||||
mprintf((" Shader in_error! Disabling deferred lighting!\n"));
|
||||
Cmdline_no_deferred_lighting = 1;
|
||||
}
|
||||
}
|
||||
@@ -17,21 +17,30 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#define MAX_SHADER_UNIFORMS 15
|
||||
#define MAX_SHADER_UNIFORMS 20
|
||||
|
||||
#define SDR_ATTRIB_RADIUS 0
|
||||
#define SDR_ATTRIB_SUBMODEL 1
|
||||
|
||||
#define MAX_SDR_ATTRIBUTES 1
|
||||
#define MAX_SDR_ATTRIBUTES 5
|
||||
|
||||
struct opengl_shader_flag_t {
|
||||
char *vert;
|
||||
char *frag;
|
||||
#define MAX_SDR_UNIFORM_BLOCKS 5
|
||||
|
||||
int flags;
|
||||
struct geometry_sdr_params
|
||||
{
|
||||
int input_type;
|
||||
int output_type;
|
||||
int vertices_out;
|
||||
};
|
||||
|
||||
struct opengl_shader_uniform_reference_t {
|
||||
int flag;
|
||||
struct opengl_shader_type_t {
|
||||
shader_type type_id;
|
||||
|
||||
char *vert;
|
||||
char *frag;
|
||||
char *geo;
|
||||
|
||||
geometry_sdr_params geo_sdr_info;
|
||||
|
||||
int num_uniforms;
|
||||
char* uniforms[MAX_SHADER_UNIFORMS];
|
||||
@@ -39,6 +48,54 @@ struct opengl_shader_uniform_reference_t {
|
||||
int num_attributes;
|
||||
char* attributes[MAX_SDR_ATTRIBUTES];
|
||||
|
||||
const char* description;
|
||||
};
|
||||
|
||||
struct opengl_shader_variant_t {
|
||||
shader_type type_id;
|
||||
|
||||
bool use_geometry_sdr;
|
||||
|
||||
int flag;
|
||||
SCP_string flag_text;
|
||||
|
||||
int num_uniforms;
|
||||
char* uniforms[MAX_SHADER_UNIFORMS];
|
||||
|
||||
int num_attributes;
|
||||
char* attributes[MAX_SDR_ATTRIBUTES];
|
||||
|
||||
const char* description;
|
||||
};
|
||||
|
||||
struct opengl_shader_file_t {
|
||||
char *vert;
|
||||
char *frag;
|
||||
char *geo;
|
||||
|
||||
int flags;
|
||||
|
||||
int num_uniforms;
|
||||
char* uniforms[MAX_SHADER_UNIFORMS];
|
||||
|
||||
int num_attributes;
|
||||
char* attributes[MAX_SDR_ATTRIBUTES];
|
||||
|
||||
const char* description;
|
||||
};
|
||||
|
||||
struct opengl_shader_uniform_reference_t {
|
||||
unsigned int flag;
|
||||
|
||||
int num_uniforms;
|
||||
char* uniforms[MAX_SHADER_UNIFORMS];
|
||||
|
||||
int num_attributes;
|
||||
char* attributes[MAX_SDR_ATTRIBUTES];
|
||||
|
||||
int num_uniform_blocks;
|
||||
char* uniform_blocks[MAX_SDR_UNIFORM_BLOCKS];
|
||||
|
||||
const char* name;
|
||||
};
|
||||
|
||||
@@ -51,10 +108,13 @@ typedef struct opengl_shader_uniform_t {
|
||||
|
||||
typedef struct opengl_shader_t {
|
||||
GLhandleARB program_id;
|
||||
int flags;
|
||||
|
||||
shader_type shader;
|
||||
unsigned int flags;
|
||||
int flags2;
|
||||
|
||||
SCP_vector<opengl_shader_uniform_t> uniforms;
|
||||
SCP_vector<opengl_shader_uniform_t> uniform_blocks;
|
||||
SCP_vector<opengl_shader_uniform_t> attributes; // using the uniform data structure to keep track of vert attribs
|
||||
|
||||
opengl_shader_t() :
|
||||
@@ -67,14 +127,18 @@ extern SCP_vector<opengl_shader_t> GL_shader;
|
||||
|
||||
extern opengl_shader_t *Current_shader;
|
||||
|
||||
int gr_opengl_maybe_create_shader(int flags);
|
||||
extern geometry_sdr_params *Current_geo_sdr_params;
|
||||
|
||||
int gr_opengl_maybe_create_shader(shader_type shader, unsigned int flags);
|
||||
void opengl_delete_shader(int sdr_handle);
|
||||
void opengl_shader_set_current(opengl_shader_t *shader_obj = NULL);
|
||||
void opengl_shader_set_current(int handle);
|
||||
|
||||
void opengl_shader_init();
|
||||
void opengl_shader_shutdown();
|
||||
|
||||
void opengl_compile_main_shader(int flags);
|
||||
GLhandleARB opengl_shader_create(const char *vs, const char *fs);
|
||||
int opengl_compile_shader(shader_type sdr, uint flags);
|
||||
GLhandleARB opengl_shader_create(const char *vs, const char *fs, const char *gs);
|
||||
|
||||
void opengl_shader_init_attribute(const char *attribute_text);
|
||||
GLint opengl_shader_get_attribute(const char *attribute_text);
|
||||
@@ -82,11 +146,17 @@ GLint opengl_shader_get_attribute(const char *attribute_text);
|
||||
void opengl_shader_init_uniform(const char *uniform_text);
|
||||
GLint opengl_shader_get_uniform(const char *uniform_text);
|
||||
|
||||
void opengl_shader_set_animated_effect(int effect);
|
||||
void opengl_shader_init_uniform_block(const char *uniform_text);
|
||||
GLint opengl_shader_get_uniform_block(const char *uniform_text);
|
||||
|
||||
|
||||
void gr_opengl_shader_set_animated_effect(int effect, float timer);
|
||||
int opengl_shader_get_animated_effect();
|
||||
void opengl_shader_set_animated_timer(float timer);
|
||||
float opengl_shader_get_animated_timer();
|
||||
|
||||
void opengl_shader_compile_deferred_light_shader();
|
||||
void opengl_shader_compile_deferred_light_clear_shader();
|
||||
|
||||
#define ANIMATED_SHADER_LOADOUTSELECT_FS1 0
|
||||
#define ANIMATED_SHADER_LOADOUTSELECT_FS2 1
|
||||
#define ANIMATED_SHADER_CLOAK 2
|
||||
|
||||
+527
-58
@@ -12,6 +12,8 @@
|
||||
#include "graphics/gropengl.h"
|
||||
#include "graphics/gropenglstate.h"
|
||||
#include "graphics/gropengllight.h"
|
||||
#include "graphics/gropenglshader.h"
|
||||
#include "math/vecmat.h"
|
||||
|
||||
extern GLfloat GL_max_anisotropy;
|
||||
|
||||
@@ -213,7 +215,8 @@ void opengl_texture_state::Enable(GLuint tex_id)
|
||||
}
|
||||
|
||||
if ( !shader_mode && (active_texture_unit < (uint)GL_supported_texture_units) ) {
|
||||
glEnable( units[active_texture_unit].texture_target );
|
||||
if( units[active_texture_unit].texture_target != GL_TEXTURE_2D_ARRAY_EXT)
|
||||
glEnable( units[active_texture_unit].texture_target );
|
||||
units[active_texture_unit].enabled = GL_TRUE;
|
||||
}
|
||||
|
||||
@@ -231,8 +234,9 @@ void opengl_texture_state::Disable()
|
||||
return;
|
||||
}
|
||||
|
||||
if ( units[active_texture_unit].enabled) {
|
||||
glDisable( units[active_texture_unit].texture_target );
|
||||
if ( units[active_texture_unit].enabled ) {
|
||||
if( units[active_texture_unit].texture_target != GL_TEXTURE_2D_ARRAY_EXT)
|
||||
glDisable( units[active_texture_unit].texture_target );
|
||||
units[active_texture_unit].enabled = GL_FALSE;
|
||||
}
|
||||
|
||||
@@ -359,14 +363,24 @@ void opengl_state::init()
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
polygonoffsetfill_Status = GL_FALSE;
|
||||
|
||||
polygon_offset_Factor = 0.0f;
|
||||
polygon_offset_Unit = 0.0f;
|
||||
|
||||
glDisable(GL_NORMALIZE);
|
||||
normalize_Status = GL_FALSE;
|
||||
|
||||
for (i = 0; i < (int)(sizeof(clipplane_Status) / sizeof(GLboolean)); i++) {
|
||||
glDisable(GL_CLIP_PLANE0+i);
|
||||
//glDisable(GL_CLIP_PLANE0+i);
|
||||
clipplane_Status[i] = GL_FALSE;
|
||||
}
|
||||
|
||||
if (GL_version >= 30) {
|
||||
for (i = 0; i < (int)(sizeof(clipdistance_Status) / sizeof(GLboolean)); i++) {
|
||||
//glDisable(GL_CLIP_DISTANCE0+i);
|
||||
clipdistance_Status[i] = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
Assert( GL_max_lights > 0 );
|
||||
light_Status = (GLboolean*) vm_malloc(GL_max_lights * sizeof(GLboolean));
|
||||
|
||||
@@ -550,6 +564,26 @@ GLboolean opengl_state::CullFace(GLint state)
|
||||
return save_state;
|
||||
}
|
||||
|
||||
void opengl_state::SetPolygonMode(GLenum face, GLenum mode)
|
||||
{
|
||||
if ( polygon_mode_Face != face || polygon_mode_Mode != mode ) {
|
||||
glPolygonMode(face, mode);
|
||||
|
||||
polygon_mode_Face = face;
|
||||
polygon_mode_Mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void opengl_state::SetPolygonOffset(GLfloat factor, GLfloat units)
|
||||
{
|
||||
if ( polygon_offset_Factor != factor || polygon_offset_Unit != units) {
|
||||
glPolygonOffset(factor, units);
|
||||
|
||||
polygon_offset_Factor = factor;
|
||||
polygon_offset_Unit = units;
|
||||
}
|
||||
}
|
||||
|
||||
GLboolean opengl_state::PolygonOffsetFill(GLint state)
|
||||
{
|
||||
GLboolean save_state = polygonoffsetfill_Status;
|
||||
@@ -626,6 +660,26 @@ GLboolean opengl_state::ClipPlane(GLint num, GLint state)
|
||||
return save_state;
|
||||
}
|
||||
|
||||
GLboolean opengl_state::ClipDistance(GLint num, GLint state)
|
||||
{
|
||||
Assert( (num >= 0) || (num < (int)(sizeof(clipdistance_Status) / sizeof(GLboolean))) || GL_version >= 30 );
|
||||
|
||||
GLboolean save_state = clipdistance_Status[num];
|
||||
|
||||
if ( !((state == -1) || (state == clipdistance_Status[num])) ) {
|
||||
if (state) {
|
||||
Assert( state == GL_TRUE );
|
||||
//glEnable(GL_CLIP_DISTANCE0+num);
|
||||
clipdistance_Status[num] = GL_TRUE;
|
||||
} else {
|
||||
//glDisable(GL_CLIP_DISTANCE0+num);
|
||||
clipdistance_Status[num] = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return save_state;
|
||||
}
|
||||
|
||||
GLboolean opengl_state::DepthMask(GLint state)
|
||||
{
|
||||
GLboolean save_state = depthmask_Status;
|
||||
@@ -720,6 +774,10 @@ void opengl_state::SetAlphaBlendMode(gr_alpha_blend ab)
|
||||
GL_state.BlendFunc(/*GL_SRC_COLOR*/GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
|
||||
break;
|
||||
|
||||
case ALPHA_BLEND_PREMULTIPLIED:
|
||||
GL_state.BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -817,7 +875,8 @@ void opengl_array_state::init(GLuint n_units)
|
||||
client_texture_units[i].stride = 0;
|
||||
client_texture_units[i].type = GL_FLOAT;
|
||||
client_texture_units[i].buffer = 0;
|
||||
client_texture_units[i].reset = false;
|
||||
client_texture_units[i].reset_ptr = false;
|
||||
client_texture_units[i].used_for_draw = false;
|
||||
}
|
||||
|
||||
color_array_Buffer = 0;
|
||||
@@ -826,14 +885,16 @@ void opengl_array_state::init(GLuint n_units)
|
||||
color_array_type = GL_FLOAT;
|
||||
color_array_stride = 0;
|
||||
color_array_pointer = 0;
|
||||
color_array_reset = false;
|
||||
color_array_reset_ptr = false;
|
||||
color_array_used_for_draw = false;
|
||||
|
||||
normal_array_Buffer = 0;
|
||||
normal_array_Status = GL_FALSE;
|
||||
normal_array_Type = GL_FLOAT;
|
||||
normal_array_Stride = 0;
|
||||
normal_array_Pointer = 0;
|
||||
normal_array_reset = false;
|
||||
normal_array_reset_ptr = false;
|
||||
normal_array_used_for_draw = false;
|
||||
|
||||
vertex_array_Buffer = 0;
|
||||
vertex_array_Status = GL_FALSE;
|
||||
@@ -841,10 +902,13 @@ void opengl_array_state::init(GLuint n_units)
|
||||
vertex_array_Type = GL_FLOAT;
|
||||
vertex_array_Stride = 0;
|
||||
vertex_array_Pointer = 0;
|
||||
vertex_array_reset = false;
|
||||
vertex_array_reset_ptr = false;
|
||||
vertex_array_used_for_draw = false;
|
||||
|
||||
array_buffer = 0;
|
||||
element_array_buffer = 0;
|
||||
texture_array_buffer = 0;
|
||||
uniform_buffer = 0;
|
||||
}
|
||||
|
||||
void opengl_array_state::SetActiveClientUnit(GLuint id)
|
||||
@@ -865,6 +929,8 @@ void opengl_array_state::SetActiveClientUnit(GLuint id)
|
||||
|
||||
void opengl_array_state::EnableClientTexture()
|
||||
{
|
||||
client_texture_units[active_client_texture_unit].used_for_draw = true;
|
||||
|
||||
if ( client_texture_units[active_client_texture_unit].status == GL_TRUE ) {
|
||||
return;
|
||||
}
|
||||
@@ -890,7 +956,7 @@ void opengl_array_state::TexPointer(GLint size, GLenum type, GLsizei stride, GLv
|
||||
opengl_client_texture_unit *ct_unit = &client_texture_units[active_client_texture_unit];
|
||||
|
||||
if (
|
||||
!ct_unit->reset
|
||||
!ct_unit->reset_ptr
|
||||
&& ct_unit->pointer == pointer
|
||||
&& ct_unit->size == size
|
||||
&& ct_unit->type == type
|
||||
@@ -907,11 +973,13 @@ void opengl_array_state::TexPointer(GLint size, GLenum type, GLsizei stride, GLv
|
||||
ct_unit->stride = stride;
|
||||
ct_unit->pointer = pointer;
|
||||
ct_unit->buffer = array_buffer;
|
||||
ct_unit->reset = false;
|
||||
ct_unit->reset_ptr = false;
|
||||
}
|
||||
|
||||
void opengl_array_state::EnableClientColor()
|
||||
{
|
||||
color_array_used_for_draw = true;
|
||||
|
||||
if ( color_array_Status == GL_TRUE ) {
|
||||
return;
|
||||
}
|
||||
@@ -935,7 +1003,7 @@ void opengl_array_state::DisableClientColor()
|
||||
void opengl_array_state::ColorPointer(GLint size, GLenum type, GLsizei stride, GLvoid *pointer)
|
||||
{
|
||||
if (
|
||||
!color_array_reset
|
||||
!color_array_reset_ptr
|
||||
&& color_array_size == size
|
||||
&& color_array_type == type
|
||||
&& color_array_stride == stride
|
||||
@@ -952,11 +1020,13 @@ void opengl_array_state::ColorPointer(GLint size, GLenum type, GLsizei stride, G
|
||||
color_array_stride = stride;
|
||||
color_array_pointer = pointer;
|
||||
color_array_Buffer = array_buffer;
|
||||
color_array_reset = false;
|
||||
color_array_reset_ptr = false;
|
||||
}
|
||||
|
||||
void opengl_array_state::EnableClientNormal()
|
||||
{
|
||||
normal_array_used_for_draw = true;
|
||||
|
||||
if ( normal_array_Status == GL_TRUE ) {
|
||||
return;
|
||||
}
|
||||
@@ -980,7 +1050,7 @@ void opengl_array_state::DisableClientNormal()
|
||||
void opengl_array_state::NormalPointer(GLenum type, GLsizei stride, GLvoid *pointer)
|
||||
{
|
||||
if (
|
||||
!normal_array_reset
|
||||
!normal_array_reset_ptr
|
||||
&& normal_array_Type == type
|
||||
&& normal_array_Stride == stride
|
||||
&& normal_array_Pointer == pointer
|
||||
@@ -995,11 +1065,13 @@ void opengl_array_state::NormalPointer(GLenum type, GLsizei stride, GLvoid *poin
|
||||
normal_array_Stride = stride;
|
||||
normal_array_Pointer = pointer;
|
||||
normal_array_Buffer = array_buffer;
|
||||
normal_array_reset = false;
|
||||
normal_array_reset_ptr = false;
|
||||
}
|
||||
|
||||
void opengl_array_state::EnableClientVertex()
|
||||
{
|
||||
vertex_array_used_for_draw = true;
|
||||
|
||||
if ( vertex_array_Status == GL_TRUE ) {
|
||||
return;
|
||||
}
|
||||
@@ -1023,7 +1095,7 @@ void opengl_array_state::DisableClientVertex()
|
||||
void opengl_array_state::VertexPointer(GLint size, GLenum type, GLsizei stride, GLvoid *pointer)
|
||||
{
|
||||
if (
|
||||
!vertex_array_reset
|
||||
!vertex_array_reset_ptr
|
||||
&& vertex_array_Size == size
|
||||
&& vertex_array_Type == type
|
||||
&& vertex_array_Stride == stride
|
||||
@@ -1040,43 +1112,35 @@ void opengl_array_state::VertexPointer(GLint size, GLenum type, GLsizei stride,
|
||||
vertex_array_Stride = stride;
|
||||
vertex_array_Pointer = pointer;
|
||||
vertex_array_Buffer = array_buffer;
|
||||
vertex_array_reset = false;
|
||||
}
|
||||
|
||||
void opengl_array_state::ResetVertexPointer()
|
||||
{
|
||||
vertex_array_Size = 4;
|
||||
vertex_array_Type = GL_FLOAT;
|
||||
vertex_array_Stride = 0;
|
||||
vertex_array_Pointer = 0;
|
||||
vertex_array_reset_ptr = false;
|
||||
}
|
||||
|
||||
void opengl_array_state::EnableVertexAttrib(GLuint index)
|
||||
{
|
||||
opengl_vertex_attrib_unit *va_unit = &vertex_attrib_units[index];
|
||||
|
||||
if ( va_unit->initialized && va_unit->status == GL_TRUE ) {
|
||||
va_unit->used_for_draw = true;
|
||||
|
||||
if ( va_unit->status_init && va_unit->status == GL_TRUE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
vglEnableVertexAttribArrayARB(index);
|
||||
va_unit->status = GL_TRUE;
|
||||
|
||||
va_unit->initialized = true;
|
||||
|
||||
va_unit->used = true;
|
||||
va_unit->status_init = true;
|
||||
}
|
||||
|
||||
void opengl_array_state::DisableVertexAttrib(GLuint index)
|
||||
{
|
||||
opengl_vertex_attrib_unit *va_unit = &vertex_attrib_units[index];
|
||||
|
||||
if ( !va_unit->initialized || va_unit->status == GL_FALSE ) {
|
||||
if ( va_unit->status_init && va_unit->status == GL_FALSE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
vglDisableVertexAttribArrayARB(index);
|
||||
va_unit->status = GL_FALSE;
|
||||
va_unit->status_init = true;
|
||||
}
|
||||
|
||||
void opengl_array_state::VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLvoid *pointer)
|
||||
@@ -1084,8 +1148,8 @@ void opengl_array_state::VertexAttribPointer(GLuint index, GLint size, GLenum ty
|
||||
opengl_vertex_attrib_unit *va_unit = &vertex_attrib_units[index];
|
||||
|
||||
if (
|
||||
!va_unit->reset
|
||||
&& va_unit->initialized
|
||||
!va_unit->reset_ptr
|
||||
&& va_unit->ptr_init
|
||||
&& va_unit->normalized == normalized
|
||||
&& va_unit->pointer == pointer
|
||||
&& va_unit->size == size
|
||||
@@ -1104,29 +1168,48 @@ void opengl_array_state::VertexAttribPointer(GLuint index, GLint size, GLenum ty
|
||||
va_unit->stride = stride;
|
||||
va_unit->type = type;
|
||||
va_unit->buffer = array_buffer;
|
||||
va_unit->reset = false;
|
||||
va_unit->reset_ptr = false;
|
||||
|
||||
va_unit->initialized = true;
|
||||
va_unit->ptr_init = true;
|
||||
}
|
||||
|
||||
void opengl_array_state::ResetVertexAttribUsed()
|
||||
void opengl_array_state::BindPointersBegin()
|
||||
{
|
||||
SCP_map<GLuint,opengl_vertex_attrib_unit>::iterator it;
|
||||
// set all available client states to not used
|
||||
vertex_array_used_for_draw = false;
|
||||
color_array_used_for_draw = false;
|
||||
normal_array_used_for_draw = false;
|
||||
|
||||
for ( it = vertex_attrib_units.begin(); it != vertex_attrib_units.end(); ++it ) {
|
||||
it->second.used = false;
|
||||
for (unsigned int i = 0; i < num_client_texture_units; i++) {
|
||||
client_texture_units[i].used_for_draw = false;
|
||||
}
|
||||
|
||||
SCP_map<GLuint, opengl_vertex_attrib_unit>::iterator it;
|
||||
|
||||
for (it = vertex_attrib_units.begin(); it != vertex_attrib_units.end(); ++it) {
|
||||
it->second.used_for_draw = false;
|
||||
}
|
||||
}
|
||||
|
||||
void opengl_array_state::DisabledVertexAttribUnused()
|
||||
void opengl_array_state::BindPointersEnd()
|
||||
{
|
||||
SCP_map<GLuint,opengl_vertex_attrib_unit>::iterator it;
|
||||
// any client states not used, disable them
|
||||
if ( !vertex_array_used_for_draw ) DisableClientVertex();
|
||||
if ( !color_array_used_for_draw ) DisableClientColor();
|
||||
if ( !normal_array_used_for_draw ) DisableClientNormal();
|
||||
|
||||
for ( it = vertex_attrib_units.begin(); it != vertex_attrib_units.end(); ++it ) {
|
||||
if ( !it->second.used ) {
|
||||
DisableVertexAttrib(it->first);
|
||||
for (unsigned int i = 0; i < num_client_texture_units; i++) {
|
||||
if ( !client_texture_units[i].used_for_draw ) {
|
||||
SetActiveClientUnit(i);
|
||||
DisableClientTexture();
|
||||
}
|
||||
}
|
||||
|
||||
SCP_map<GLuint, opengl_vertex_attrib_unit>::iterator it;
|
||||
|
||||
for (it = vertex_attrib_units.begin(); it != vertex_attrib_units.end(); ++it) {
|
||||
if ( !it->second.used_for_draw ) DisableVertexAttrib(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
void opengl_array_state::BindArrayBuffer(GLuint id)
|
||||
@@ -1139,18 +1222,18 @@ void opengl_array_state::BindArrayBuffer(GLuint id)
|
||||
|
||||
array_buffer = id;
|
||||
|
||||
vertex_array_reset = true;
|
||||
color_array_reset = true;
|
||||
normal_array_reset = true;
|
||||
vertex_array_reset_ptr = true;
|
||||
color_array_reset_ptr = true;
|
||||
normal_array_reset_ptr = true;
|
||||
|
||||
for (unsigned int i = 0; i < num_client_texture_units; i++) {
|
||||
client_texture_units[i].reset = true;
|
||||
client_texture_units[i].reset_ptr = true;
|
||||
}
|
||||
|
||||
SCP_map<GLuint,opengl_vertex_attrib_unit>::iterator it;
|
||||
|
||||
for ( it = vertex_attrib_units.begin(); it != vertex_attrib_units.end(); ++it ) {
|
||||
it->second.reset = true;
|
||||
it->second.reset_ptr = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1165,20 +1248,406 @@ void opengl_array_state::BindElementBuffer(GLuint id)
|
||||
element_array_buffer = id;
|
||||
}
|
||||
|
||||
void gr_opengl_flush_data_states()
|
||||
void opengl_array_state::BindTextureBuffer(GLuint id)
|
||||
{
|
||||
GL_state.Array.SetActiveClientUnit(1);
|
||||
GL_state.Array.DisableClientTexture();
|
||||
if ( !Is_Extension_Enabled(OGL_ARB_TEXTURE_BUFFER) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
GL_state.Array.SetActiveClientUnit(0);
|
||||
GL_state.Array.DisableClientTexture();
|
||||
if ( texture_array_buffer == id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
GL_state.Array.DisableClientColor();
|
||||
GL_state.Array.DisableClientNormal();
|
||||
GL_state.Array.DisableClientVertex();
|
||||
vglBindBufferARB(GL_TEXTURE_BUFFER_ARB, id);
|
||||
|
||||
GL_state.Array.ResetVertexAttribUsed();
|
||||
GL_state.Array.DisabledVertexAttribUnused();
|
||||
texture_array_buffer = id;
|
||||
}
|
||||
|
||||
void opengl_array_state::BindUniformBufferBindingIndex(GLuint id, GLuint index)
|
||||
{
|
||||
if ( !Is_Extension_Enabled(OGL_ARB_UNIFORM_BUFFER_OBJECT) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( uniform_buffer_index_bindings[index] == id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
vglBindBufferBaseEXT(GL_UNIFORM_BUFFER, index, id);
|
||||
|
||||
uniform_buffer_index_bindings[index] = id;
|
||||
}
|
||||
|
||||
void opengl_array_state::BindUniformBuffer(GLuint id)
|
||||
{
|
||||
if ( !Is_Extension_Enabled(OGL_ARB_UNIFORM_BUFFER_OBJECT) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( uniform_buffer == id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
vglBindBufferARB(GL_UNIFORM_BUFFER, id);
|
||||
|
||||
uniform_buffer = id;
|
||||
}
|
||||
|
||||
opengl_uniform_state::opengl_uniform_state()
|
||||
{
|
||||
}
|
||||
|
||||
int opengl_uniform_state::findUniform(const SCP_string &name)
|
||||
{
|
||||
SCP_map<SCP_string, int>::iterator iter;
|
||||
|
||||
iter = uniform_lookup.find(name);
|
||||
|
||||
if ( iter == uniform_lookup.end() ) {
|
||||
return -1;
|
||||
} else {
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
void opengl_uniform_state::setUniformi(const SCP_string &name, const int val)
|
||||
{
|
||||
int uniform_index = findUniform(name);
|
||||
bool resident = false;
|
||||
|
||||
if ( uniform_index >= 0) {
|
||||
Assert( (size_t)uniform_index < uniforms.size() );
|
||||
|
||||
uniform_bind *bind_info = &uniforms[uniform_index];
|
||||
|
||||
if ( bind_info->type == uniform_bind::INT ) {
|
||||
if ( uniform_data_ints[bind_info->index] == val ) {
|
||||
return;
|
||||
}
|
||||
|
||||
uniform_data_ints[bind_info->index] = val;
|
||||
resident = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !resident ) {
|
||||
// uniform doesn't exist in our previous uniform block so queue this new value
|
||||
uniform_data_ints.push_back(val);
|
||||
|
||||
uniform_bind new_bind;
|
||||
|
||||
new_bind.count = 1;
|
||||
new_bind.index = uniform_data_ints.size() - 1;
|
||||
new_bind.type = uniform_bind::INT;
|
||||
new_bind.name = name;
|
||||
|
||||
uniforms.push_back(new_bind);
|
||||
|
||||
uniform_lookup[name] = uniforms.size()-1;
|
||||
}
|
||||
|
||||
vglUniform1iARB(opengl_shader_get_uniform(name.c_str()), val);
|
||||
}
|
||||
|
||||
void opengl_uniform_state::setUniformf(const SCP_string &name, const float val)
|
||||
{
|
||||
int uniform_index = findUniform(name);
|
||||
bool resident = false;
|
||||
|
||||
if ( uniform_index >= 0) {
|
||||
Assert( (size_t)uniform_index < uniforms.size() );
|
||||
|
||||
uniform_bind *bind_info = &uniforms[uniform_index];
|
||||
|
||||
if ( bind_info->type == uniform_bind::FLOAT ) {
|
||||
if ( fl_equal(uniform_data_floats[bind_info->index], val) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
uniform_data_floats[bind_info->index] = val;
|
||||
resident = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !resident ) {
|
||||
// uniform doesn't exist in our previous uniform block so queue this new value
|
||||
uniform_data_floats.push_back(val);
|
||||
|
||||
uniform_bind new_bind;
|
||||
|
||||
new_bind.count = 1;
|
||||
new_bind.index = uniform_data_floats.size() - 1;
|
||||
new_bind.type = uniform_bind::FLOAT;
|
||||
new_bind.name = name;
|
||||
|
||||
uniforms.push_back(new_bind);
|
||||
|
||||
uniform_lookup[name] = uniforms.size()-1;
|
||||
}
|
||||
|
||||
vglUniform1fARB(opengl_shader_get_uniform(name.c_str()), val);
|
||||
}
|
||||
|
||||
void opengl_uniform_state::setUniform2f(const SCP_string &name, const float x, const float y)
|
||||
{
|
||||
vec2d temp;
|
||||
|
||||
temp.x = x;
|
||||
temp.y = y;
|
||||
|
||||
setUniform2f(name, temp);
|
||||
}
|
||||
|
||||
void opengl_uniform_state::setUniform2f(const SCP_string &name, const vec2d &val)
|
||||
{
|
||||
int uniform_index = findUniform(name);
|
||||
bool resident = false;
|
||||
|
||||
if ( uniform_index >= 0 ) {
|
||||
Assert( (size_t)uniform_index < uniforms.size() );
|
||||
|
||||
uniform_bind *bind_info = &uniforms[uniform_index];
|
||||
|
||||
if ( bind_info->type == uniform_bind::VEC2 ) {
|
||||
if ( vm_vec_equal(uniform_data_vec2d[bind_info->index], val) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
uniform_data_vec2d[bind_info->index] = val;
|
||||
resident = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !resident ) {
|
||||
// uniform doesn't exist in our previous uniform block so queue this new value
|
||||
uniform_data_vec2d.push_back(val);
|
||||
|
||||
uniform_bind new_bind;
|
||||
|
||||
new_bind.count = 1;
|
||||
new_bind.index = uniform_data_vec2d.size() - 1;
|
||||
new_bind.type = uniform_bind::VEC2;
|
||||
new_bind.name = name;
|
||||
|
||||
uniforms.push_back(new_bind);
|
||||
|
||||
uniform_lookup[name] = uniforms.size()-1;
|
||||
}
|
||||
|
||||
vglUniform2fARB(opengl_shader_get_uniform(name.c_str()), val.x, val.y);
|
||||
}
|
||||
|
||||
void opengl_uniform_state::setUniform3f(const SCP_string &name, const float x, const float y, const float z)
|
||||
{
|
||||
vec3d temp;
|
||||
|
||||
temp.xyz.x = x;
|
||||
temp.xyz.y = y;
|
||||
temp.xyz.z = z;
|
||||
|
||||
setUniform3f(name, temp);
|
||||
}
|
||||
|
||||
void opengl_uniform_state::setUniform3f(const SCP_string &name, const vec3d &val)
|
||||
{
|
||||
int uniform_index = findUniform(name);
|
||||
bool resident = false;
|
||||
|
||||
if ( uniform_index >= 0 ) {
|
||||
Assert( (size_t)uniform_index < uniforms.size() );
|
||||
|
||||
uniform_bind *bind_info = &uniforms[uniform_index];
|
||||
|
||||
if ( bind_info->type == uniform_bind::VEC3 ) {
|
||||
if ( vm_vec_equal(uniform_data_vec3d[bind_info->index], val) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
uniform_data_vec3d[bind_info->index] = val;
|
||||
resident = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !resident ) {
|
||||
// uniform doesn't exist in our previous uniform block so queue this new value
|
||||
uniform_data_vec3d.push_back(val);
|
||||
|
||||
uniform_bind new_bind;
|
||||
|
||||
new_bind.count = 1;
|
||||
new_bind.index = uniform_data_vec3d.size() - 1;
|
||||
new_bind.type = uniform_bind::VEC3;
|
||||
new_bind.name = name;
|
||||
|
||||
uniforms.push_back(new_bind);
|
||||
|
||||
uniform_lookup[name] = uniforms.size()-1;
|
||||
}
|
||||
|
||||
vglUniform3fARB(opengl_shader_get_uniform(name.c_str()), val.a1d[0], val.a1d[1], val.a1d[2]);
|
||||
}
|
||||
|
||||
void opengl_uniform_state::setUniform4f(const SCP_string &name, const vec4 &val)
|
||||
{
|
||||
int uniform_index = findUniform(name);
|
||||
bool resident = false;
|
||||
|
||||
if ( uniform_index >= 0 ) {
|
||||
Assert( (size_t)uniform_index < uniforms.size() );
|
||||
|
||||
uniform_bind *bind_info = &uniforms[uniform_index];
|
||||
|
||||
if ( bind_info->type == uniform_bind::VEC4 ) {
|
||||
if ( vm_vec_equal(uniform_data_vec4[bind_info->index], val) ) {
|
||||
// if the values are close enough, pass.
|
||||
return;
|
||||
}
|
||||
|
||||
uniform_data_vec4[bind_info->index] = val;
|
||||
resident = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !resident ) {
|
||||
// uniform doesn't exist in our previous uniform block so queue this new value
|
||||
uniform_data_vec4.push_back(val);
|
||||
|
||||
uniform_bind new_bind;
|
||||
|
||||
new_bind.count = 1;
|
||||
new_bind.index = uniform_data_vec4.size() - 1;
|
||||
new_bind.type = uniform_bind::VEC4;
|
||||
new_bind.name = name;
|
||||
|
||||
uniforms.push_back(new_bind);
|
||||
|
||||
uniform_lookup[name] = uniforms.size()-1;
|
||||
}
|
||||
|
||||
vglUniform4fARB(opengl_shader_get_uniform(name.c_str()), val.a1d[0], val.a1d[1], val.a1d[2], val.a1d[3]);
|
||||
}
|
||||
|
||||
void opengl_uniform_state::setUniformMatrix4f(const SCP_string &name, const matrix4 &val)
|
||||
{
|
||||
int uniform_index = findUniform(name);
|
||||
bool resident = false;
|
||||
|
||||
if ( uniform_index >= 0) {
|
||||
Assert( (size_t)uniform_index < uniforms.size() );
|
||||
|
||||
uniform_bind *bind_info = &uniforms[uniform_index];
|
||||
|
||||
if ( bind_info->type == uniform_bind::MATRIX4 && bind_info->count == 1 ) {
|
||||
if ( vm_matrix_equal(uniform_data_matrix4[bind_info->index], val) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
uniform_data_matrix4[bind_info->index] = val;
|
||||
resident = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !resident ) {
|
||||
// uniform doesn't exist in our previous uniform block so queue this new value
|
||||
//matrix_uniform_data[num_matrix_uniforms] = val;
|
||||
//memcpy(&(matrix_uniform_data[num_matrix_uniforms]), &val, sizeof(matrix4));
|
||||
uniform_data_matrix4.push_back(val);
|
||||
// num_matrix_uniforms += 1;
|
||||
|
||||
uniform_bind new_bind;
|
||||
new_bind.count = 1;
|
||||
new_bind.index = uniform_data_matrix4.size() - 1;
|
||||
// new_bind.index = num_matrix_uniforms - 1;
|
||||
new_bind.type = uniform_bind::MATRIX4;
|
||||
new_bind.name = name;
|
||||
|
||||
uniforms.push_back(new_bind);
|
||||
|
||||
uniform_lookup[name] = uniforms.size()-1;
|
||||
}
|
||||
|
||||
vglUniformMatrix4fvARB(opengl_shader_get_uniform(name.c_str()), 1, GL_FALSE, (const GLfloat*)&val);
|
||||
}
|
||||
|
||||
void opengl_uniform_state::setUniformMatrix4fv(const SCP_string &name, const int count, const matrix4 *val)
|
||||
{
|
||||
int uniform_index = findUniform(name);
|
||||
bool resident = false;
|
||||
|
||||
if ( uniform_index >= 0) {
|
||||
Assert( (size_t)uniform_index < uniforms.size() );
|
||||
|
||||
uniform_bind *bind_info = &uniforms[uniform_index];
|
||||
|
||||
if ( bind_info->type == uniform_bind::MATRIX4 && bind_info->count == count ) {
|
||||
bool equal = true;
|
||||
|
||||
// if the values are close enough, pass.
|
||||
for ( int i = 0; i < count; ++i ) {
|
||||
if ( !vm_matrix_equal(val[i], uniform_data_matrix4[bind_info->index+i]) ) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( equal ) {
|
||||
return;
|
||||
}
|
||||
|
||||
resident = true;
|
||||
for ( int i = 0; i < count; ++i ) {
|
||||
uniform_data_matrix4[bind_info->index+i] = val[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !resident ) {
|
||||
// uniform doesn't exist in our previous uniform block so queue this new value
|
||||
for ( int i = 0; i < count; ++i ) {
|
||||
uniform_data_matrix4.push_back(val[i]);
|
||||
}
|
||||
|
||||
uniform_bind new_bind;
|
||||
new_bind.count = count;
|
||||
new_bind.index = uniform_data_matrix4.size() - count;
|
||||
// new_bind.index = num_matrix_uniforms - count;
|
||||
new_bind.type = uniform_bind::MATRIX4;
|
||||
new_bind.name = name;
|
||||
|
||||
uniforms.push_back(new_bind);
|
||||
|
||||
uniform_lookup[name] = uniforms.size()-1;
|
||||
}
|
||||
|
||||
vglUniformMatrix4fvARB(opengl_shader_get_uniform(name.c_str()), count, GL_FALSE, (const GLfloat*)val);
|
||||
}
|
||||
|
||||
void opengl_uniform_state::reset()
|
||||
{
|
||||
uniforms.clear();
|
||||
|
||||
uniform_data_ints.clear();
|
||||
uniform_data_floats.clear();
|
||||
uniform_data_vec2d.clear();
|
||||
uniform_data_vec3d.clear();
|
||||
uniform_data_vec4.clear();
|
||||
uniform_data_matrix4.clear();
|
||||
|
||||
uniform_lookup.clear();
|
||||
}
|
||||
|
||||
void gr_opengl_clear_states()
|
||||
{
|
||||
GL_state.Texture.DisableAll();
|
||||
|
||||
gr_zbias(0);
|
||||
gr_zbuffer_set(ZBUFFER_TYPE_READ);
|
||||
gr_set_cull(0);
|
||||
gr_set_fill_mode(GR_FILL_MODE_SOLID);
|
||||
gr_reset_lighting();
|
||||
gr_set_lighting(false, false);
|
||||
|
||||
opengl_shader_set_current();
|
||||
}
|
||||
|
||||
void opengl_setup_render_states(int &r, int &g, int &b, int &alpha, int &tmap_type, int flags, int is_scaler)
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
|
||||
#define MAX_UNIFORM_BUFFERS 6
|
||||
|
||||
struct opengl_texture_unit {
|
||||
GLboolean active; // unit is active
|
||||
GLboolean enabled; // has texture target enabled
|
||||
@@ -177,7 +179,9 @@ struct opengl_client_texture_unit
|
||||
GLenum type;
|
||||
GLsizei stride;
|
||||
GLvoid *pointer;
|
||||
bool reset;
|
||||
|
||||
bool reset_ptr;
|
||||
bool used_for_draw;
|
||||
};
|
||||
|
||||
struct opengl_vertex_attrib_unit
|
||||
@@ -191,9 +195,11 @@ struct opengl_vertex_attrib_unit
|
||||
GLsizei stride;
|
||||
GLvoid *pointer;
|
||||
|
||||
bool used;
|
||||
bool initialized;
|
||||
bool reset;
|
||||
bool status_init;
|
||||
bool ptr_init;
|
||||
|
||||
bool reset_ptr;
|
||||
bool used_for_draw;
|
||||
};
|
||||
|
||||
class opengl_array_state
|
||||
@@ -210,14 +216,16 @@ class opengl_array_state
|
||||
GLenum color_array_type;
|
||||
GLsizei color_array_stride;
|
||||
GLvoid *color_array_pointer;
|
||||
bool color_array_reset;
|
||||
bool color_array_reset_ptr;
|
||||
bool color_array_used_for_draw;
|
||||
|
||||
GLboolean normal_array_Status;
|
||||
GLuint normal_array_Buffer;
|
||||
GLenum normal_array_Type;
|
||||
GLsizei normal_array_Stride;
|
||||
GLvoid *normal_array_Pointer;
|
||||
bool normal_array_reset;
|
||||
bool normal_array_reset_ptr;
|
||||
bool normal_array_used_for_draw;
|
||||
|
||||
GLboolean vertex_array_Status;
|
||||
GLuint vertex_array_Buffer;
|
||||
@@ -225,14 +233,23 @@ class opengl_array_state
|
||||
GLenum vertex_array_Type;
|
||||
GLsizei vertex_array_Stride;
|
||||
GLvoid *vertex_array_Pointer;
|
||||
bool vertex_array_reset;
|
||||
bool vertex_array_reset_ptr;
|
||||
bool vertex_array_used_for_draw;
|
||||
|
||||
SCP_map<GLuint, opengl_vertex_attrib_unit> vertex_attrib_units;
|
||||
|
||||
GLuint array_buffer;
|
||||
GLuint element_array_buffer;
|
||||
GLuint texture_array_buffer;
|
||||
GLuint uniform_buffer;
|
||||
|
||||
GLuint uniform_buffer_index_bindings[MAX_UNIFORM_BUFFERS];
|
||||
public:
|
||||
opengl_array_state(): active_client_texture_unit(0), client_texture_units(NULL) {}
|
||||
opengl_array_state(): active_client_texture_unit(0), client_texture_units(NULL) {
|
||||
for ( int i = 0; i < MAX_UNIFORM_BUFFERS; ++i ) {
|
||||
uniform_buffer_index_bindings[i] = 0;
|
||||
}
|
||||
}
|
||||
~opengl_array_state();
|
||||
|
||||
void init(GLuint n_units);
|
||||
@@ -253,16 +270,69 @@ class opengl_array_state
|
||||
void EnableClientVertex();
|
||||
void DisableClientVertex();
|
||||
void VertexPointer(GLint size, GLenum type, GLsizei stride, GLvoid *pointer);
|
||||
void ResetVertexPointer();
|
||||
|
||||
void ResetVertexAttribUsed();
|
||||
void DisabledVertexAttribUnused();
|
||||
void EnableVertexAttrib(GLuint index);
|
||||
void DisableVertexAttrib(GLuint index);
|
||||
void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLvoid *pointer);
|
||||
|
||||
void BindPointersBegin();
|
||||
void BindPointersEnd();
|
||||
|
||||
void BindArrayBuffer(GLuint id);
|
||||
void BindElementBuffer(GLuint id);
|
||||
void BindTextureBuffer(GLuint id);
|
||||
void BindUniformBuffer(GLuint id);
|
||||
void BindUniformBufferBindingIndex(GLuint id, GLuint index);
|
||||
};
|
||||
|
||||
struct uniform_bind
|
||||
{
|
||||
SCP_string name;
|
||||
|
||||
enum data_type {
|
||||
INT,
|
||||
FLOAT,
|
||||
VEC2,
|
||||
VEC3,
|
||||
VEC4,
|
||||
MATRIX4
|
||||
};
|
||||
|
||||
uniform_bind::data_type type;
|
||||
int index;
|
||||
|
||||
int count;
|
||||
int tranpose;
|
||||
};
|
||||
|
||||
class opengl_uniform_state
|
||||
{
|
||||
SCP_vector<uniform_bind> uniforms;
|
||||
|
||||
SCP_vector<int> uniform_data_ints;
|
||||
SCP_vector<float> uniform_data_floats;
|
||||
SCP_vector<vec2d> uniform_data_vec2d;
|
||||
SCP_vector<vec3d> uniform_data_vec3d;
|
||||
SCP_vector<vec4> uniform_data_vec4;
|
||||
SCP_vector<matrix4> uniform_data_matrix4;
|
||||
|
||||
SCP_map<SCP_string, int> uniform_lookup;
|
||||
|
||||
int findUniform(const SCP_string &name);
|
||||
public:
|
||||
opengl_uniform_state();
|
||||
|
||||
void setUniformi(const SCP_string &name, const int value);
|
||||
void setUniformf(const SCP_string &name, const float value);
|
||||
void setUniform2f(const SCP_string &name, const float x, const float y);
|
||||
void setUniform2f(const SCP_string &name, const vec2d &val);
|
||||
void setUniform3f(const SCP_string &name, const float x, const float y, const float z);
|
||||
void setUniform3f(const SCP_string &name, const vec3d &value);
|
||||
void setUniform4f(const SCP_string &name, const vec4 &val);
|
||||
void setUniformMatrix4fv(const SCP_string &name, const int count, const matrix4 *value);
|
||||
void setUniformMatrix4f(const SCP_string &name, const matrix4 &val);
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
class opengl_state
|
||||
@@ -280,6 +350,7 @@ class opengl_state
|
||||
GLboolean polygonoffsetfill_Status;
|
||||
GLboolean normalize_Status;
|
||||
GLboolean clipplane_Status[6];
|
||||
GLboolean clipdistance_Status[6];
|
||||
GLboolean *light_Status;
|
||||
GLboolean depthmask_Status;
|
||||
GLboolean lighting_Status;
|
||||
@@ -295,11 +366,15 @@ class opengl_state
|
||||
GLenum blendfunc_Value[2];
|
||||
GLenum depthfunc_Value;
|
||||
|
||||
GLenum polygon_mode_Face;
|
||||
GLenum polygon_mode_Mode;
|
||||
|
||||
GLfloat polygon_offset_Factor;
|
||||
GLfloat polygon_offset_Unit;
|
||||
|
||||
gr_alpha_blend Current_alpha_blend_mode;
|
||||
gr_zbuffer_type Current_zbuffer_type;
|
||||
gr_stencil_type Current_stencil_type;
|
||||
|
||||
|
||||
public:
|
||||
opengl_state() : light_Status(NULL) {}
|
||||
~opengl_state();
|
||||
@@ -308,11 +383,14 @@ class opengl_state
|
||||
|
||||
opengl_texture_state Texture;
|
||||
opengl_array_state Array;
|
||||
opengl_uniform_state Uniform;
|
||||
|
||||
void SetTextureSource(gr_texture_source ts);
|
||||
void SetAlphaBlendMode(gr_alpha_blend ab);
|
||||
void SetZbufferType(gr_zbuffer_type zt);
|
||||
void SetStencilType(gr_stencil_type st);
|
||||
void SetPolygonOffset(GLfloat factor, GLfloat units);
|
||||
void SetPolygonMode(GLenum face, GLenum mode);
|
||||
|
||||
// the GLboolean functions will return the current state if no argument
|
||||
// and the previous state if an argument is passed
|
||||
@@ -328,6 +406,7 @@ class opengl_state
|
||||
GLboolean Normalize(GLint state = -1);
|
||||
GLboolean Light(GLint num, GLint state = -1);
|
||||
GLboolean ClipPlane(GLint num, GLint state = -1);
|
||||
GLboolean ClipDistance(GLint num, GLint state = -1);
|
||||
GLboolean DepthMask(GLint state = -1);
|
||||
GLboolean ColorMask(GLint state = -1);
|
||||
|
||||
@@ -425,7 +504,7 @@ inline void opengl_state::InvalidateColor()
|
||||
|
||||
extern opengl_state GL_state;
|
||||
|
||||
void gr_opengl_flush_data_states();
|
||||
void gr_opengl_clear_states();
|
||||
void opengl_setup_render_states(int &r,int &g,int &b,int &alpha, int &tmap_type, int flags, int is_scaler = 0);
|
||||
|
||||
|
||||
|
||||
@@ -1311,10 +1311,56 @@ int opengl_compress_image( ubyte **compressed_data, ubyte *in_data, int width, i
|
||||
return compressed_size;
|
||||
}
|
||||
|
||||
void gr_opengl_get_bitmap_from_texture(void* data_out, int bitmap_num)
|
||||
{
|
||||
float u,v;
|
||||
|
||||
gr_opengl_tcache_set(bitmap_num, TCACHE_TYPE_NORMAL, &u, &v);
|
||||
|
||||
int n = bm_get_cache_slot(bitmap_num, 1);
|
||||
tcache_slot_opengl *ts = &Textures[n];
|
||||
|
||||
GLenum pixel_format = GL_RGB;
|
||||
GLenum data_format = GL_FLOAT;
|
||||
int bytes_per_pixel = 3 * sizeof(float);
|
||||
|
||||
if ( bm_has_alpha_channel(bitmap_num) ) {
|
||||
pixel_format = GL_RGBA;
|
||||
bytes_per_pixel = 4 * sizeof(float);
|
||||
}
|
||||
|
||||
opengl_get_texture(ts->texture_target, pixel_format, data_format, 1, ts->w, ts->h, bytes_per_pixel, data_out, 0);
|
||||
}
|
||||
|
||||
int opengl_get_texture( GLenum target, GLenum pixel_format, GLenum data_format, int num_mipmaps, int width, int height, int bytes_per_pixel, void* image_data, int offset )
|
||||
{
|
||||
int m_offset = offset;
|
||||
int m_width = width;
|
||||
int m_height = height;
|
||||
|
||||
for ( int i = 0; i < num_mipmaps; i++ ) {
|
||||
glGetTexImage(target, i, pixel_format, data_format, (ubyte*)image_data + m_offset);
|
||||
|
||||
m_offset += (m_width * m_height * bytes_per_pixel);
|
||||
|
||||
// reduce by half for next mipmap level
|
||||
m_width >>= 1;
|
||||
m_height >>= 1;
|
||||
|
||||
if (m_width < 1)
|
||||
m_width = 1;
|
||||
|
||||
if (m_height < 1)
|
||||
m_height = 1;
|
||||
}
|
||||
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
// sends a texture object out to "image_data", which should be memory which is already allocated
|
||||
// this should only be used for uncompressed 24-bit or 32-bit (distiguished by "alpha" var) images
|
||||
// returns 0 on failure, size of data on success
|
||||
int opengl_export_image( int slot, int width, int height, int alpha, int num_mipmaps, ubyte *image_data )
|
||||
int opengl_export_render_target( int slot, int width, int height, int alpha, int num_mipmaps, ubyte *image_data )
|
||||
{
|
||||
tcache_slot_opengl *ts = &Textures[slot];
|
||||
|
||||
@@ -1360,25 +1406,17 @@ int opengl_export_image( int slot, int width, int height, int alpha, int num_mip
|
||||
GL_state.Texture.Enable(ts->texture_id);
|
||||
|
||||
for (int i = 0; i < faces; i++) {
|
||||
for (int j = 0; j < ts->mipmap_levels; j++) {
|
||||
glGetTexImage(target + i, j, (alpha) ? GL_BGRA : GL_BGR, (alpha) ? GL_UNSIGNED_INT_8_8_8_8_REV : GL_UNSIGNED_BYTE, image_data + m_offset);
|
||||
|
||||
m_offset += (m_width * m_height * m_bpp);
|
||||
|
||||
// reduce by half for next mipmap level
|
||||
m_width >>= 1;
|
||||
m_height >>= 1;
|
||||
|
||||
if (m_width < 1)
|
||||
m_width = 1;
|
||||
|
||||
if (m_height < 1)
|
||||
m_height = 1;
|
||||
}
|
||||
|
||||
// restore original width and height for next face
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_offset = opengl_get_texture(
|
||||
target + i,
|
||||
(alpha) ? GL_BGRA : GL_BGR,
|
||||
(alpha) ? GL_UNSIGNED_INT_8_8_8_8_REV : GL_UNSIGNED_BYTE,
|
||||
ts->mipmap_levels,
|
||||
m_width,
|
||||
m_height,
|
||||
m_bpp,
|
||||
image_data,
|
||||
m_offset
|
||||
);
|
||||
}
|
||||
|
||||
GL_state.Texture.Disable();
|
||||
@@ -1946,4 +1984,3 @@ GLuint opengl_get_rtt_framebuffer()
|
||||
//
|
||||
// End of GL_EXT_framebuffer_object stuff
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -75,7 +75,9 @@ GLfloat opengl_get_max_anisotropy();
|
||||
void opengl_kill_render_target(int slot);
|
||||
int opengl_make_render_target(int handle, int slot, int *w, int *h, ubyte *bpp, int *mm_lvl, int flags);
|
||||
int opengl_set_render_target(int slot, int face = -1, int is_static = 0);
|
||||
int opengl_export_image(int slot, int width, int height, int alpha, int num_mipmaps, ubyte *image_data = NULL);
|
||||
void gr_opengl_get_bitmap_from_texture(void* data_out, int bitmap_num);
|
||||
int opengl_get_texture(GLenum target, GLenum pixel_format, GLenum data_format, int num_mipmaps, int width, int height, int bytes_per_pixel, void* image_data, int offset);
|
||||
int opengl_export_render_target( int slot, int width, int height, int alpha, int num_mipmaps, ubyte *image_data );
|
||||
void opengl_set_texture_target(GLenum target = GL_TEXTURE_2D);
|
||||
void opengl_set_texture_face(GLenum face = GL_TEXTURE_2D);
|
||||
|
||||
|
||||
+800
-430
File diff suppressed because it is too large.
Load diff
@@ -14,8 +14,10 @@
|
||||
#define _GROPENGLTNL_H
|
||||
|
||||
|
||||
#include "graphics/gropengl.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include "model/model.h"
|
||||
#include "graphics/shadows.h"
|
||||
|
||||
extern GLint GL_max_elements_vertices;
|
||||
extern GLint GL_max_elements_indices;
|
||||
@@ -23,6 +25,12 @@ extern GLint GL_max_elements_indices;
|
||||
class poly_list;
|
||||
class vertex_buffer;
|
||||
|
||||
extern float shadow_veryneardist;
|
||||
extern float shadow_neardist;
|
||||
extern float shadow_middist;
|
||||
extern float shadow_fardist;
|
||||
extern bool Rendering_to_shadow_map;
|
||||
|
||||
void gr_opengl_start_instance_matrix(vec3d *offset, matrix *rotation);
|
||||
void gr_opengl_start_instance_angles(vec3d *pos, angles *rotation);
|
||||
void gr_opengl_end_instance_matrix();
|
||||
@@ -40,25 +48,32 @@ void gr_opengl_end_clip_plane();
|
||||
|
||||
int gr_opengl_create_buffer();
|
||||
bool gr_opengl_pack_buffer(const int buffer_id, vertex_buffer *vb);
|
||||
bool gr_opengl_config_buffer(const int buffer_id, vertex_buffer *vb);
|
||||
bool gr_opengl_config_buffer(const int buffer_id, vertex_buffer *vb, bool update_ibuffer_only);
|
||||
void gr_opengl_destroy_buffer(int idx);
|
||||
void gr_opengl_set_buffer(int idx);
|
||||
void gr_opengl_render_buffer(int start, const vertex_buffer *bufferp, int texi, int flags);
|
||||
void gr_opengl_render_to_env(int FACE);
|
||||
|
||||
int gr_opengl_create_stream_buffer();
|
||||
void gr_opengl_update_stream_buffer(int buffer, effect_vertex *buffer_data, uint size);
|
||||
void gr_opengl_render_stream_buffer(int offset, int n_verts, int flags);
|
||||
void gr_opengl_render_stream_buffer_start(int buffer_id);
|
||||
void gr_opengl_render_stream_buffer_end();
|
||||
void gr_opengl_update_buffer_object(int handle, uint size, void* data);
|
||||
void opengl_delete_buffer_object(int handle);
|
||||
|
||||
void gr_opengl_update_transform_buffer(void* data, uint size);
|
||||
void gr_opengl_set_transform_buffer_offset(int offset);
|
||||
|
||||
int gr_opengl_create_stream_buffer_object();
|
||||
void gr_opengl_render_stream_buffer(int buffer_handle, int offset, int n_verts, int flags);
|
||||
|
||||
void gr_opengl_start_state_block();
|
||||
int gr_opengl_end_state_block();
|
||||
void gr_opengl_set_state_block(int);
|
||||
|
||||
void gr_opengl_set_team_color(const SCP_string &team, const SCP_string &secondaryteam = "none", fix timestamp = 0, int fadetime = 0);
|
||||
void gr_opengl_disable_team_color();
|
||||
void gr_opengl_set_thrust_scale(float scale = -1.0f);
|
||||
void gr_opengl_set_team_color(team_color *colors);
|
||||
|
||||
void opengl_tnl_shutdown();
|
||||
|
||||
void opengl_tnl_set_material(int flags, uint shader_flags, int tmap_type);
|
||||
void opengl_tnl_set_material_distortion(uint flags);
|
||||
void opengl_tnl_set_material_soft_particle(uint flags);
|
||||
|
||||
#endif //_GROPENGLTNL_H
|
||||
+80
-25
@@ -35,7 +35,7 @@ bool gr_stub_pack_buffer(const int buffer_id, vertex_buffer *vb)
|
||||
}
|
||||
|
||||
// NOTE: should return a failure
|
||||
bool gr_stub_config_buffer(const int buffer_id, vertex_buffer *vb)
|
||||
bool gr_stub_config_buffer(const int buffer_id, vertex_buffer *vb, bool update_ibuffer_only)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -102,6 +102,10 @@ void gr_stub_center_alpha( int type)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_set_thrust_scale(float scale)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_circle( int xc, int yc, int d, int resize_mode )
|
||||
{
|
||||
}
|
||||
@@ -271,24 +275,27 @@ void gr_stub_set_buffer(int idx)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_update_buffer_object(int handle, uint size, void* data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void gr_stub_update_transform_buffer(void* data, uint size)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void gr_stub_set_transform_buffer_offset(int offset)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int gr_stub_create_stream_buffer()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void gr_stub_update_stream_buffer(int buffer, effect_vertex *buffer_data, uint size)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_render_stream_buffer(int offset, int n_verts, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_render_stream_buffer_start(int buffer_id)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_render_stream_buffer_end()
|
||||
void gr_stub_render_stream_buffer(int buffer_handle, int offset, int n_verts, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -318,6 +325,10 @@ void gr_stub_set_lighting(bool set, bool state)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_set_light_factor(float factor)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_set_light(light *light)
|
||||
{
|
||||
}
|
||||
@@ -420,6 +431,10 @@ void gr_stub_post_process_save_zbuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_post_process_blur_shadow_map()
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_post_process_begin()
|
||||
{
|
||||
}
|
||||
@@ -436,6 +451,22 @@ void gr_stub_scene_texture_end()
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_copy_effect_texture()
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_deferred_lighting_begin()
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_deferred_lighting_end()
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_deferred_lighting_finish()
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_set_ambient_light(int red, int green, int blue)
|
||||
{
|
||||
}
|
||||
@@ -478,7 +509,7 @@ void gr_stub_draw_line_list(colored_vector *lines, int num)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_flush_data_states()
|
||||
void gr_stub_clear_states()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -486,6 +517,11 @@ void gr_stub_update_texture(int bitmap_handle, int bpp, ubyte* data, int width,
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_get_bitmap_from_texture(void* data_out, int bitmap_num)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// bitmap functions
|
||||
int gr_stub_bm_load(ubyte type, int n, const char *filename, CFILE *img_cfp, int *w, int *h, int *bpp, ubyte *c_type, int *mm_lvl, int *size)
|
||||
{
|
||||
@@ -697,17 +733,24 @@ void gr_stub_bm_page_in_start()
|
||||
{
|
||||
}
|
||||
|
||||
int gr_stub_maybe_create_shader(int flags) {
|
||||
int gr_stub_maybe_create_shader(shader_type shader, unsigned int flags) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void gr_stub_set_team_color(const SCP_string &team, const SCP_string &secondaryteam, fix timestamp, int fadetime) {
|
||||
void gr_stub_set_animated_effect(int effect, float timer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void gr_stub_enable_team_color() {
|
||||
void gr_stub_set_team_color(team_color *colors) {
|
||||
}
|
||||
|
||||
void gr_stub_disable_team_color() {
|
||||
void gr_stub_shadow_map_start(matrix4 *shadow_view_matrix, matrix* light_matrix)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_shadow_map_end()
|
||||
{
|
||||
}
|
||||
|
||||
bool gr_stub_init()
|
||||
@@ -833,11 +876,12 @@ bool gr_stub_init()
|
||||
gr_screen.gf_render_buffer = gr_stub_render_buffer;
|
||||
gr_screen.gf_set_buffer = gr_stub_set_buffer;
|
||||
|
||||
gr_screen.gf_update_transform_buffer = gr_stub_update_transform_buffer;
|
||||
gr_screen.gf_update_buffer_object = gr_stub_update_buffer_object;
|
||||
gr_screen.gf_set_transform_buffer_offset = gr_stub_set_transform_buffer_offset;
|
||||
|
||||
gr_screen.gf_create_stream_buffer = gr_stub_create_stream_buffer;
|
||||
gr_screen.gf_update_stream_buffer = gr_stub_update_stream_buffer;
|
||||
gr_screen.gf_render_stream_buffer = gr_stub_render_stream_buffer;
|
||||
gr_screen.gf_render_stream_buffer_start = gr_stub_render_stream_buffer_start;
|
||||
gr_screen.gf_render_stream_buffer_end = gr_stub_render_stream_buffer_end;
|
||||
|
||||
gr_screen.gf_start_instance_matrix = gr_stub_start_instance_matrix;
|
||||
gr_screen.gf_end_instance_matrix = gr_stub_end_instance_matrix;
|
||||
@@ -859,11 +903,17 @@ bool gr_stub_init()
|
||||
|
||||
gr_screen.gf_scene_texture_begin = gr_stub_scene_texture_begin;
|
||||
gr_screen.gf_scene_texture_end = gr_stub_scene_texture_end;
|
||||
gr_screen.gf_copy_effect_texture = gr_stub_copy_effect_texture;
|
||||
|
||||
gr_screen.gf_deferred_lighting_begin = gr_stub_deferred_lighting_begin;
|
||||
gr_screen.gf_deferred_lighting_end = gr_stub_deferred_lighting_end;
|
||||
gr_screen.gf_deferred_lighting_finish = gr_stub_deferred_lighting_finish;
|
||||
|
||||
gr_screen.gf_start_clip_plane = gr_stub_start_clip_plane;
|
||||
gr_screen.gf_end_clip_plane = gr_stub_end_clip_plane;
|
||||
|
||||
gr_screen.gf_lighting = gr_stub_set_lighting;
|
||||
gr_screen.gf_set_light_factor = gr_stub_set_light_factor;
|
||||
|
||||
gr_screen.gf_set_proj_matrix = gr_stub_set_projection_matrix;
|
||||
gr_screen.gf_end_proj_matrix = gr_stub_end_projection_matrix;
|
||||
@@ -874,6 +924,7 @@ bool gr_stub_init()
|
||||
gr_screen.gf_push_scale_matrix = gr_stub_push_scale_matrix;
|
||||
gr_screen.gf_pop_scale_matrix = gr_stub_pop_scale_matrix;
|
||||
gr_screen.gf_center_alpha = gr_stub_center_alpha;
|
||||
gr_screen.gf_set_thrust_scale = gr_stub_set_thrust_scale;
|
||||
|
||||
gr_screen.gf_setup_background_fog = gr_stub_setup_background_fog;
|
||||
|
||||
@@ -888,14 +939,18 @@ bool gr_stub_init()
|
||||
gr_screen.gf_line_htl = gr_stub_draw_htl_line;
|
||||
gr_screen.gf_sphere_htl = gr_stub_draw_htl_sphere;
|
||||
|
||||
gr_screen.gf_shadow_map_start = gr_stub_shadow_map_start;
|
||||
gr_screen.gf_shadow_map_end = gr_stub_shadow_map_end;
|
||||
|
||||
gr_screen.gf_maybe_create_shader = gr_stub_maybe_create_shader;
|
||||
|
||||
gr_screen.gf_flush_data_states = gr_stub_flush_data_states;
|
||||
gr_screen.gf_set_animated_effect = gr_stub_set_animated_effect;
|
||||
|
||||
gr_screen.gf_clear_states = gr_stub_clear_states;
|
||||
|
||||
gr_screen.gf_set_team_color = gr_stub_set_team_color;
|
||||
gr_screen.gf_enable_team_color = gr_stub_enable_team_color;
|
||||
gr_screen.gf_disable_team_color = gr_stub_disable_team_color;
|
||||
|
||||
gr_screen.gf_update_texture = gr_stub_update_texture;
|
||||
gr_screen.gf_get_bitmap_from_texture = gr_stub_get_bitmap_from_texture;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "graphics/shadows.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "math/vecmat.h"
|
||||
#include "object/object.h"
|
||||
#include "lighting/lighting.h"
|
||||
#include "graphics/gropengltnl.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "render/3d.h"
|
||||
#include "model/model.h"
|
||||
#include "model/modelrender.h"
|
||||
#include "debris/debris.h"
|
||||
#include "asteroid/asteroid.h"
|
||||
#include "graphics/gropengldraw.h"
|
||||
|
||||
extern vec3d check_offsets[8];
|
||||
|
||||
matrix4 Shadow_view_matrix;
|
||||
matrix4 Shadow_proj_matrix[MAX_SHADOW_CASCADES];
|
||||
float Shadow_cascade_distances[MAX_SHADOW_CASCADES];
|
||||
|
||||
light_frustum_info Shadow_frustums[MAX_SHADOW_CASCADES];
|
||||
|
||||
bool shadows_obj_in_frustum(object *objp, matrix *light_orient, vec3d *min, vec3d *max)
|
||||
{
|
||||
int i;
|
||||
vec3d pts[8], tmp, pt, pos_lightspace, pos_viewspace;
|
||||
vec3d obj_min = ZERO_VECTOR;
|
||||
vec3d obj_max = ZERO_VECTOR;
|
||||
|
||||
vec3d pos, pos_rot;
|
||||
|
||||
vm_vec_sub(&pos, &objp->pos, &Eye_position);
|
||||
vm_vec_rotate(&pos_rot, &pos, light_orient);
|
||||
|
||||
if ( (pos_rot.xyz.x - objp->radius) > max->xyz.x
|
||||
|| (pos_rot.xyz.x + objp->radius) < min->xyz.x
|
||||
|| (pos_rot.xyz.y - objp->radius) > max->xyz.y
|
||||
|| (pos_rot.xyz.y + objp->radius) < min->xyz.y
|
||||
|| (pos_rot.xyz.z - objp->radius) > max->xyz.z ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void shadows_construct_light_proj(light_frustum_info *shadow_data)
|
||||
{
|
||||
memset(&shadow_data->proj_matrix, 0, sizeof(matrix4));
|
||||
|
||||
shadow_data->proj_matrix.a1d[0] = 2.0f / ( shadow_data->max.xyz.x - shadow_data->min.xyz.x );
|
||||
shadow_data->proj_matrix.a1d[5] = 2.0f / ( shadow_data->max.xyz.y - shadow_data->min.xyz.y );
|
||||
shadow_data->proj_matrix.a1d[10] = -2.0f / ( shadow_data->max.xyz.z - shadow_data->min.xyz.z );
|
||||
shadow_data->proj_matrix.a1d[12] = -(shadow_data->max.xyz.x + shadow_data->min.xyz.x) / ( shadow_data->max.xyz.x - shadow_data->min.xyz.x );
|
||||
shadow_data->proj_matrix.a1d[13] = -(shadow_data->max.xyz.y + shadow_data->min.xyz.y) / ( shadow_data->max.xyz.y - shadow_data->min.xyz.y );
|
||||
shadow_data->proj_matrix.a1d[14] = -(shadow_data->max.xyz.z + shadow_data->min.xyz.z) / ( shadow_data->max.xyz.z - shadow_data->min.xyz.z );
|
||||
shadow_data->proj_matrix.a1d[15] = 1.0f;
|
||||
}
|
||||
|
||||
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 shadows_construct_light_frustum(light_frustum_info *shadow_data, matrix *light_matrix, 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.5f) * 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);
|
||||
|
||||
vec3d frustum_pts[8];
|
||||
|
||||
// bring frustum points into light space
|
||||
vm_vec_rotate(&frustum_pts[0], &near_bottom_left, light_matrix);
|
||||
vm_vec_rotate(&frustum_pts[1], &near_bottom_right, light_matrix);
|
||||
vm_vec_rotate(&frustum_pts[2], &near_top_right, light_matrix);
|
||||
vm_vec_rotate(&frustum_pts[3], &near_top_left, light_matrix);
|
||||
vm_vec_rotate(&frustum_pts[4], &far_top_left, light_matrix);
|
||||
vm_vec_rotate(&frustum_pts[5], &far_top_right, light_matrix);
|
||||
vm_vec_rotate(&frustum_pts[6], &far_bottom_right, light_matrix);
|
||||
vm_vec_rotate(&frustum_pts[7], &far_bottom_left, light_matrix);
|
||||
|
||||
vec3d min = ZERO_VECTOR;
|
||||
vec3d max = ZERO_VECTOR;
|
||||
|
||||
min = frustum_pts[0];
|
||||
max = frustum_pts[0];
|
||||
|
||||
// find min and max of frustum points
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if ( frustum_pts[i].xyz.x < min.xyz.x ) {
|
||||
min.xyz.x = frustum_pts[i].xyz.x;
|
||||
}
|
||||
|
||||
if ( frustum_pts[i].xyz.x > max.xyz.x ) {
|
||||
max.xyz.x = frustum_pts[i].xyz.x;
|
||||
}
|
||||
|
||||
if ( frustum_pts[i].xyz.y < min.xyz.y ) {
|
||||
min.xyz.y = frustum_pts[i].xyz.y;
|
||||
}
|
||||
|
||||
if ( frustum_pts[i].xyz.y > max.xyz.y ) {
|
||||
max.xyz.y = frustum_pts[i].xyz.y;
|
||||
}
|
||||
|
||||
if ( frustum_pts[i].xyz.z < min.xyz.z ) {
|
||||
min.xyz.z = frustum_pts[i].xyz.z;
|
||||
}
|
||||
|
||||
if ( frustum_pts[i].xyz.z > max.xyz.z ) {
|
||||
max.xyz.z = frustum_pts[i].xyz.z;
|
||||
}
|
||||
}
|
||||
|
||||
shadow_data->min = min;
|
||||
shadow_data->max = max;
|
||||
|
||||
shadows_construct_light_proj(shadow_data);
|
||||
}
|
||||
|
||||
matrix shadows_start_render(matrix *eye_orient, vec3d *eye_pos, float fov, float aspect, float veryneardist, float neardist, float middist, float fardist)
|
||||
{
|
||||
if(Static_light.empty())
|
||||
return vmd_identity_matrix;
|
||||
|
||||
light *lp = *(Static_light.begin());
|
||||
|
||||
if ( lp == NULL ) {
|
||||
return vmd_identity_matrix;
|
||||
}
|
||||
|
||||
vec3d light_dir;
|
||||
matrix light_matrix;
|
||||
|
||||
vm_vec_copy_normalize(&light_dir, &lp->vec);
|
||||
vm_vector_2_matrix(&light_matrix, &light_dir, &eye_orient->vec.uvec, NULL);
|
||||
|
||||
shadows_construct_light_frustum(&Shadow_frustums[0], &light_matrix, eye_orient, eye_pos, fov, aspect, 0.0f, veryneardist);
|
||||
shadows_construct_light_frustum(&Shadow_frustums[1], &light_matrix, eye_orient, eye_pos, fov, aspect, veryneardist - (veryneardist - 0.0f)* 0.2f, neardist);
|
||||
shadows_construct_light_frustum(&Shadow_frustums[2], &light_matrix, eye_orient, eye_pos, fov, aspect, neardist - (neardist - veryneardist) * 0.2f, middist);
|
||||
shadows_construct_light_frustum(&Shadow_frustums[3], &light_matrix, eye_orient, eye_pos, fov, aspect, middist - (middist - neardist) * 0.2f, fardist);
|
||||
|
||||
Shadow_cascade_distances[0] = veryneardist;
|
||||
Shadow_cascade_distances[1] = neardist;
|
||||
Shadow_cascade_distances[2] = middist;
|
||||
Shadow_cascade_distances[3] = fardist;
|
||||
|
||||
Shadow_proj_matrix[0] = Shadow_frustums[0].proj_matrix;
|
||||
Shadow_proj_matrix[1] = Shadow_frustums[1].proj_matrix;
|
||||
Shadow_proj_matrix[2] = Shadow_frustums[2].proj_matrix;
|
||||
Shadow_proj_matrix[3] = Shadow_frustums[3].proj_matrix;
|
||||
|
||||
gr_shadow_map_start(&Shadow_view_matrix, &light_matrix);
|
||||
|
||||
return light_matrix;
|
||||
}
|
||||
|
||||
void shadows_end_render()
|
||||
{
|
||||
gr_shadow_map_end();
|
||||
}
|
||||
|
||||
void shadows_render_all(float fov, matrix *eye_orient, vec3d *eye_pos)
|
||||
{
|
||||
if ( Static_light.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
light *lp = *(Static_light.begin());
|
||||
|
||||
if( Cmdline_nohtl || !Cmdline_shadow_quality || !lp ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//shadows_debug_show_frustum(&Player_obj->orient, &Player_obj->pos, fov, gr_screen.clip_aspect, Min_draw_distance, 3000.0f);
|
||||
|
||||
gr_end_proj_matrix();
|
||||
gr_end_view_matrix();
|
||||
|
||||
// these cascade distances are a result of some arbitrary tuning to give a good balance of quality and banding.
|
||||
// maybe we could use a more programmatic algorithim?
|
||||
matrix light_matrix = shadows_start_render(eye_orient, eye_pos, fov, gr_screen.clip_aspect, 200.0f, 600.0f, 2500.0f, 8000.0f);
|
||||
|
||||
draw_list scene;
|
||||
object *objp = Objects;
|
||||
|
||||
for ( int i = 0; i <= Highest_object_index; i++, objp++ ) {
|
||||
bool cull = true;
|
||||
|
||||
for ( int j = 0; j < MAX_SHADOW_CASCADES; ++j ) {
|
||||
if ( shadows_obj_in_frustum(objp, &light_matrix, &Shadow_frustums[j].min, &Shadow_frustums[j].max) ) {
|
||||
cull = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( cull ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(objp->type)
|
||||
{
|
||||
case OBJ_SHIP:
|
||||
{
|
||||
obj_queue_render(objp, &scene);
|
||||
}
|
||||
break;
|
||||
case OBJ_ASTEROID:
|
||||
{
|
||||
model_render_params render_info;
|
||||
|
||||
render_info.set_object_number(OBJ_INDEX(objp));
|
||||
render_info.set_flags(MR_IS_ASTEROID | MR_NO_TEXTURING | MR_NO_LIGHTING);
|
||||
|
||||
model_clear_instance( Asteroid_info[Asteroids[objp->instance].asteroid_type].model_num[Asteroids[objp->instance].asteroid_subtype]);
|
||||
model_render_queue(&render_info, &scene, Asteroid_info[Asteroids[objp->instance].asteroid_type].model_num[Asteroids[objp->instance].asteroid_subtype], &objp->orient, &objp->pos);
|
||||
}
|
||||
break;
|
||||
|
||||
case OBJ_DEBRIS:
|
||||
{
|
||||
debris *db;
|
||||
db = &Debris[objp->instance];
|
||||
|
||||
if ( !(db->flags & DEBRIS_USED)){
|
||||
continue;
|
||||
}
|
||||
|
||||
objp = &Objects[db->objnum];
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
render_info.set_flags(MR_NO_TEXTURING | MR_NO_LIGHTING);
|
||||
|
||||
submodel_render_queue(&render_info, &scene, db->model_num, db->submodel_num, &objp->orient, &objp->pos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scene.init_render();
|
||||
scene.render_all(GR_ZBUFF_FULL);
|
||||
|
||||
shadows_end_render();
|
||||
|
||||
gr_zbias(0);
|
||||
gr_zbuffer_set(ZBUFFER_TYPE_READ);
|
||||
gr_set_cull(0);
|
||||
|
||||
gr_clear_states();
|
||||
gr_set_buffer(-1);
|
||||
|
||||
GL_state.Texture.DisableAll();
|
||||
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "object/object.h"
|
||||
|
||||
#ifndef _SHADOWS_H
|
||||
#define _SHADOWS_H
|
||||
|
||||
#define MAX_SHADOW_CASCADES 4
|
||||
|
||||
struct light_frustum_info
|
||||
{
|
||||
matrix4 proj_matrix;
|
||||
|
||||
vec3d min;
|
||||
vec3d max;
|
||||
|
||||
float start_dist;
|
||||
};
|
||||
|
||||
extern matrix4 Shadow_view_matrix;
|
||||
extern matrix4 Shadow_proj_matrix[MAX_SHADOW_CASCADES];
|
||||
extern float Shadow_cascade_distances[MAX_SHADOW_CASCADES];
|
||||
|
||||
void shadows_construct_light_frustum(vec3d *min_out, vec3d *max_out, vec3d light_vec, matrix *orient, vec3d *pos, float fov, float aspect, float z_near, float z_far);
|
||||
bool shadows_obj_in_frustum(object *objp, vec3d *min, vec3d *max, matrix *light_orient);
|
||||
void shadows_render_all(float fov, matrix *eye_orient, vec3d *eye_pos);
|
||||
|
||||
matrix shadows_start_render(matrix *eye_orient, vec3d *eye_pos, float fov, float aspect, float veryneardist, float neardist, float middist, float fardist);
|
||||
void shadows_end_render();
|
||||
|
||||
#endif
|
||||
@@ -51,7 +51,7 @@ extern void grx_tmapper( int nv, vertex * verts[], uint flags );
|
||||
// Add any entries that don't work for software under here:
|
||||
// Make sure to disable them at top of grx_tmapper
|
||||
#define TMAP_FLAG_ALPHA (1<<8) // Has an alpha component
|
||||
#define TMAP_FLAG_NONDARKENING (1<<9) // RGB=255,255,255 doesn't darken
|
||||
#define TMAP_FLAG_BATCH_TRANSFORMS (1<<9) // Use batched transform data transmitted via texture/uniform buffer
|
||||
|
||||
// Interface specific stuff (for separate filtering, sizing, etc.), replaces old TMAP_FLAG_BITMAP_SECTION
|
||||
#define TMAP_FLAG_INTERFACE (1<<10)
|
||||
@@ -61,7 +61,7 @@ extern void grx_tmapper( int nv, vertex * verts[], uint flags );
|
||||
|
||||
// RT Flags added to determine whats being drawn for HT&L
|
||||
#define TMAP_HTL_3D_UNLIT (1<<12)
|
||||
#define TMAP_HTL_2D (1<<13)
|
||||
#define TMAP_HTL_2D (1<<13) // I don't think this flag is being used (Swifty)
|
||||
|
||||
//tristrips, for trails mostly, might find other uses eventualy
|
||||
#define TMAP_FLAG_TRISTRIP (1<<14)
|
||||
@@ -86,6 +86,11 @@ extern void grx_tmapper( int nv, vertex * verts[], uint flags );
|
||||
|
||||
#define TMAP_FLAG_DESATURATE (1<<23)
|
||||
|
||||
#define TMAP_FLAG_POINTLIST (1<<24)
|
||||
#define TMAP_FLAG_LINESTRIP (1<<25)
|
||||
#define TMAP_FLAG_LINES (1<<26)
|
||||
#define TMAP_FLAG_VERTEX_GEN (1<<27)
|
||||
|
||||
#define TMAP_ADDRESS_WRAP 1
|
||||
#define TMAP_ADDRESS_MIRROR 2
|
||||
#define TMAP_ADDRESS_CLAMP 3
|
||||
|
||||
@@ -667,7 +667,6 @@ void HudGaugeShield::showShields(object *objp, int mode)
|
||||
g3_start_frame(1);
|
||||
hud_save_restore_camera_data(1);
|
||||
setClip(sx, sy, 112, 93);
|
||||
model_set_detail_level(1);
|
||||
|
||||
//if(!digitus_improbus)
|
||||
g3_set_view_matrix( &sip->closeup_pos, &vmd_identity_matrix, sip->closeup_zoom * 2.5f);
|
||||
@@ -686,7 +685,13 @@ void HudGaugeShield::showShields(object *objp, int mode)
|
||||
ship_model_start(objp);
|
||||
//if(!digitus_improbus)
|
||||
{
|
||||
model_render( sip->model_num, &object_orient, &vmd_zero_vector, MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING, -1, -1, sp->ship_replacement_textures);
|
||||
model_render_params render_info;
|
||||
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_AUTOCENTER | MR_NO_FOGGING);
|
||||
render_info.set_replacement_textures(sp->ship_replacement_textures);
|
||||
render_info.set_detail_level_lock(1);
|
||||
|
||||
model_render_immediate( &render_info, sip->model_num, &object_orient, &vmd_zero_vector );
|
||||
}
|
||||
/*else
|
||||
{
|
||||
|
||||
+37
-15
@@ -7125,7 +7125,6 @@ void HudGaugeHardpoints::render(float frametime)
|
||||
g3_start_frame(1);
|
||||
hud_save_restore_camera_data(1);
|
||||
setClip(sx, sy, _size[0], _size[1]);
|
||||
model_set_detail_level(1);
|
||||
|
||||
g3_set_view_matrix( &sip->closeup_pos, &vmd_identity_matrix, sip->closeup_zoom*1.5f);
|
||||
|
||||
@@ -7137,31 +7136,36 @@ void HudGaugeHardpoints::render(float frametime)
|
||||
setGaugeColor();
|
||||
|
||||
//We're ready to show stuff
|
||||
model_render_params render_info;
|
||||
|
||||
int detail_level_lock = 1;
|
||||
int cull = gr_set_cull(0);
|
||||
gr_stencil_clear();
|
||||
gr_stencil_set(GR_STENCIL_WRITE);
|
||||
int zbuffer = gr_zbuffer_set(GR_ZBUFF_NONE);
|
||||
gr_set_color_buffer(0);
|
||||
|
||||
render_info.set_outline_color(gauge_color.red, gauge_color.green, gauge_color.blue);
|
||||
render_info.set_detail_level_lock(detail_level_lock);
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_TEXTURING | MR_NO_CULL);
|
||||
|
||||
ship_model_start(objp);
|
||||
model_render( sip->model_num, &object_orient, &vmd_zero_vector, MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_TEXTURING | MR_NO_CULL);
|
||||
model_render_immediate( &render_info, sip->model_num, &object_orient, &vmd_zero_vector);
|
||||
|
||||
gr_set_color_buffer(1);
|
||||
gr_stencil_set(GR_STENCIL_READ);
|
||||
gr_set_cull(cull);
|
||||
gr_set_line_width(_line_width*2.0f);
|
||||
|
||||
model_set_alpha( gr_screen.current_color.alpha / 255.0f );
|
||||
model_set_forced_texture(0);
|
||||
//model_set_alpha( gr_screen.current_color.alpha / 255.0f );
|
||||
//model_set_forced_texture(0);
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_TEXTURING | MR_SHOW_OUTLINE_HTL | MR_NO_POLYS | MR_NO_ZBUFFER | MR_NO_CULL);
|
||||
|
||||
model_set_outline_color_fast(&gauge_color);
|
||||
|
||||
model_render(
|
||||
model_render_immediate(
|
||||
&render_info,
|
||||
sip->model_num,
|
||||
&object_orient,
|
||||
&vmd_zero_vector,
|
||||
MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_TEXTURING | MR_SHOW_OUTLINE_HTL | MR_NO_POLYS | MR_NO_ZBUFFER | MR_NO_CULL | MR_ALL_XPARENT
|
||||
&vmd_zero_vector
|
||||
);
|
||||
ship_model_stop( objp );
|
||||
|
||||
@@ -7176,10 +7180,10 @@ void HudGaugeHardpoints::render(float frametime)
|
||||
vec3d subobj_pos;
|
||||
g3_start_instance_matrix(&vmd_zero_vector, &object_orient, true);
|
||||
|
||||
int render_flags = MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_TEXTURING | MR_NO_ZBUFFER;
|
||||
int render_flags = MR_NO_LIGHTING | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_TEXTURING | MR_NO_ZBUFFER;
|
||||
|
||||
setGaugeColor();
|
||||
model_set_alpha( gr_screen.current_color.alpha / 255.0f );
|
||||
float alpha = gr_screen.current_color.alpha / 255.0f;
|
||||
|
||||
//secondary weapons
|
||||
int num_secondaries_rendered = 0;
|
||||
@@ -7195,7 +7199,13 @@ void HudGaugeHardpoints::render(float frametime)
|
||||
|
||||
if (Weapon_info[swp->secondary_bank_weapons[i]].wi_flags2 & WIF2_EXTERNAL_WEAPON_LNCH) {
|
||||
for(k = 0; k < bank->num_slots; k++) {
|
||||
model_render(Weapon_info[swp->secondary_bank_weapons[i]].external_model_num, &vmd_identity_matrix, &bank->pnt[k], render_flags);
|
||||
model_render_params weapon_render_info;
|
||||
|
||||
weapon_render_info.set_detail_level_lock(detail_level_lock);
|
||||
weapon_render_info.set_flags(render_flags);
|
||||
weapon_render_info.set_alpha(alpha);
|
||||
|
||||
model_render_immediate(&weapon_render_info, Weapon_info[swp->secondary_bank_weapons[i]].external_model_num, &vmd_identity_matrix, &bank->pnt[k]);
|
||||
}
|
||||
} else {
|
||||
num_secondaries_rendered = 0;
|
||||
@@ -7221,14 +7231,19 @@ void HudGaugeHardpoints::render(float frametime)
|
||||
|
||||
vm_vec_scale_add2(&secondary_weapon_pos, &vmd_z_vector, -(1.0f-sp->secondary_point_reload_pct[i][k]) * model_get(Weapon_info[swp->secondary_bank_weapons[i]].external_model_num)->rad);
|
||||
|
||||
model_render(Weapon_info[swp->secondary_bank_weapons[i]].external_model_num, &vmd_identity_matrix, &secondary_weapon_pos, render_flags);
|
||||
model_render_params weapon_render_info;
|
||||
|
||||
weapon_render_info.set_detail_level_lock(detail_level_lock);
|
||||
weapon_render_info.set_flags(render_flags);
|
||||
weapon_render_info.set_alpha(alpha);
|
||||
|
||||
model_render_immediate(&weapon_render_info, Weapon_info[swp->secondary_bank_weapons[i]].external_model_num, &vmd_identity_matrix, &secondary_weapon_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g3_done_instance(true);
|
||||
resetClip();
|
||||
model_set_forced_texture(0);
|
||||
|
||||
setGaugeColor(HUD_C_BRIGHT);
|
||||
|
||||
@@ -7255,8 +7270,15 @@ void HudGaugeHardpoints::render(float frametime)
|
||||
//renderCircle(xc, yc, 25);
|
||||
} else {
|
||||
polymodel* pm = model_get(Weapon_info[swp->primary_bank_weapons[i]].external_model_num);
|
||||
|
||||
|
||||
model_render_params weapon_render_info;
|
||||
weapon_render_info.set_detail_level_lock(detail_level_lock);
|
||||
weapon_render_info.set_flags(render_flags);
|
||||
weapon_render_info.set_alpha(alpha);
|
||||
|
||||
pm->gun_submodel_rotation = sp->primary_rotate_ang[i];
|
||||
model_render(Weapon_info[swp->primary_bank_weapons[i]].external_model_num, &vmd_identity_matrix, &bank->pnt[k], render_flags);
|
||||
model_render_immediate(&weapon_render_info, Weapon_info[swp->primary_bank_weapons[i]].external_model_num, &vmd_identity_matrix, &bank->pnt[k]);
|
||||
pm->gun_submodel_rotation = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
+72
-55
@@ -571,6 +571,7 @@ void HudGaugeTargetBox::renderTargetShip(object *target_objp)
|
||||
// is largely copied over from renderTargetShip(). To keep the codes similar please update
|
||||
// both if and when needed
|
||||
ship_model_start( target_objp );
|
||||
model_render_params render_info;
|
||||
|
||||
switch (Targetbox_wire) {
|
||||
case 0:
|
||||
@@ -579,25 +580,25 @@ void HudGaugeTargetBox::renderTargetShip(object *target_objp)
|
||||
break;
|
||||
case 1:
|
||||
if (ship_is_tagged(target_objp))
|
||||
model_set_outline_color_fast(iff_get_color(IFF_COLOR_TAGGED, 1));
|
||||
render_info.set_outline_color(*iff_get_color(IFF_COLOR_TAGGED, 1));
|
||||
else
|
||||
model_set_outline_color_fast(iff_get_color_by_team_and_object(target_shipp->team, Player_ship->team, 1, target_objp));
|
||||
render_info.set_outline_color(*iff_get_color_by_team_and_object(target_shipp->team, Player_ship->team, 1, target_objp));
|
||||
|
||||
if (Ship_info[Ships[target_objp->instance].ship_info_index].uses_team_colors) {
|
||||
gr_set_team_color(Ships[target_objp->instance].team_name, Ships[target_objp->instance].secondary_team_name, Ships[target_objp->instance].team_change_timestamp, Ships[target_objp->instance].team_change_time);
|
||||
if (target_sip->uses_team_colors) {
|
||||
render_info.set_team_color(target_shipp->team_name, target_shipp->secondary_team_name, target_shipp->team_change_timestamp, target_shipp->team_change_time);
|
||||
}
|
||||
|
||||
flags = (Cmdline_nohtl) ? MR_SHOW_OUTLINE : MR_SHOW_OUTLINE_HTL;
|
||||
flags |= MR_NO_POLYS | MR_NO_LIGHTING;
|
||||
flags |= MR_NO_POLYS | MR_NO_LIGHTING | MR_NO_TEXTURING;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
if (ship_is_tagged(target_objp))
|
||||
model_set_outline_color_fast(iff_get_color(IFF_COLOR_TAGGED, 1));
|
||||
render_info.set_outline_color(*iff_get_color(IFF_COLOR_TAGGED, 1));
|
||||
else
|
||||
model_set_outline_color_fast(iff_get_color_by_team_and_object(target_shipp->team, Player_ship->team, 1, target_objp));
|
||||
render_info.set_outline_color(*iff_get_color_by_team_and_object(target_shipp->team, Player_ship->team, 1, target_objp));
|
||||
|
||||
flags |= MR_NO_LIGHTING | MR_NO_TEXTURING;
|
||||
|
||||
@@ -605,19 +606,20 @@ void HudGaugeTargetBox::renderTargetShip(object *target_objp)
|
||||
}
|
||||
|
||||
if (target_sip->hud_target_lod >= 0) {
|
||||
model_set_detail_level(target_sip->hud_target_lod);
|
||||
render_info.set_detail_level_lock(target_sip->hud_target_lod);
|
||||
}
|
||||
|
||||
if(Targetbox_shader_effect > -1) {
|
||||
flags |= MR_ANIMATED_SHADER;
|
||||
|
||||
opengl_shader_set_animated_effect(Targetbox_shader_effect);
|
||||
render_info.set_animated_effect(Targetbox_shader_effect, 0.0f);
|
||||
}
|
||||
|
||||
if ( Monitor_mask >= 0 ) {
|
||||
gr_stencil_set(GR_STENCIL_READ);
|
||||
}
|
||||
Interp_desaturate = Desaturated;
|
||||
|
||||
if ( Desaturated ) {
|
||||
flags |= MR_DESATURATED;
|
||||
}
|
||||
|
||||
if (!Glowpoint_override)
|
||||
Glowpoint_override = true;
|
||||
@@ -628,18 +630,21 @@ void HudGaugeTargetBox::renderTargetShip(object *target_objp)
|
||||
flags |= MR_NO_GLOWMAPS;
|
||||
}
|
||||
|
||||
render_info.set_flags(flags | MR_AUTOCENTER | MR_NO_FOGGING);
|
||||
|
||||
// maybe render a special hud-target-only model
|
||||
if(target_sip->model_num_hud >= 0){
|
||||
model_render( target_sip->model_num_hud, &target_objp->orient, &obj_pos, flags | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING);
|
||||
model_render_immediate( &render_info, target_sip->model_num_hud, &target_objp->orient, &obj_pos);
|
||||
} else {
|
||||
model_render( target_sip->model_num, &target_objp->orient, &obj_pos, flags | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING, -1, -1, target_shipp->ship_replacement_textures);
|
||||
render_info.set_replacement_textures(target_shipp->ship_replacement_textures);
|
||||
|
||||
model_render_immediate( &render_info, target_sip->model_num, &target_objp->orient, &obj_pos);
|
||||
}
|
||||
|
||||
Interp_desaturate = false;
|
||||
Glowpoint_override = false;
|
||||
|
||||
ship_model_stop( target_objp );
|
||||
gr_disable_team_color();
|
||||
|
||||
if ( Monitor_mask >= 0 ) {
|
||||
gr_stencil_set(GR_STENCIL_NONE);
|
||||
@@ -725,22 +730,24 @@ void HudGaugeTargetBox::renderTargetDebris(object *target_objp)
|
||||
renderTargetSetup(&camera_eye, &camera_orient, 0.5f);
|
||||
model_clear_instance(debrisp->model_num);
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
switch (Targetbox_wire) {
|
||||
case 0:
|
||||
flags |= MR_NO_LIGHTING;
|
||||
|
||||
break;
|
||||
case 1:
|
||||
model_set_outline_color(255,255,255);
|
||||
render_info.set_outline_color(255, 255, 255);
|
||||
|
||||
flags = (Cmdline_nohtl) ? MR_SHOW_OUTLINE : MR_SHOW_OUTLINE_HTL;
|
||||
flags |= MR_NO_POLYS | MR_NO_LIGHTING;
|
||||
flags |= MR_NO_POLYS | MR_NO_LIGHTING | MR_NO_TEXTURING;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
model_set_outline_color(255,255,255);
|
||||
render_info.set_outline_color(255, 255, 255);
|
||||
|
||||
flags |= MR_NO_LIGHTING | MR_NO_TEXTURING;
|
||||
|
||||
@@ -748,21 +755,21 @@ void HudGaugeTargetBox::renderTargetDebris(object *target_objp)
|
||||
}
|
||||
|
||||
if(Targetbox_shader_effect > -1) {
|
||||
flags |= MR_ANIMATED_SHADER;
|
||||
|
||||
opengl_shader_set_animated_effect(Targetbox_shader_effect);
|
||||
render_info.set_animated_effect(Targetbox_shader_effect, 0.0f);
|
||||
}
|
||||
|
||||
if ( Monitor_mask >= 0 ) {
|
||||
gr_stencil_set(GR_STENCIL_READ);
|
||||
}
|
||||
|
||||
Interp_desaturate = Desaturated;
|
||||
if ( Desaturated ) {
|
||||
flags |= MR_DESATURATED;
|
||||
}
|
||||
|
||||
render_info.set_flags(flags | MR_NO_FOGGING);
|
||||
|
||||
// This calls the colour that doesn't get reset
|
||||
submodel_render( debrisp->model_num, debrisp->submodel_num, &target_objp->orient, &obj_pos, flags | MR_LOCK_DETAIL | MR_NO_FOGGING );
|
||||
|
||||
Interp_desaturate = false;
|
||||
submodel_render_immediate( &render_info, debrisp->model_num, debrisp->submodel_num, &target_objp->orient, &obj_pos);
|
||||
|
||||
if ( Monitor_mask >= 0 ) {
|
||||
gr_stencil_set(GR_STENCIL_NONE);
|
||||
@@ -884,6 +891,8 @@ void HudGaugeTargetBox::renderTargetWeapon(object *target_objp)
|
||||
renderTargetSetup(&camera_eye, &camera_orient, View_zoom/3);
|
||||
model_clear_instance(viewed_model_num);
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
// IMPORTANT NOTE! Code handling the rendering when 'missile_view == TRUE' is largely copied over from
|
||||
// renderTargetShip(). To keep the codes similar please update both if and when needed
|
||||
if (missile_view == FALSE) {
|
||||
@@ -893,16 +902,16 @@ void HudGaugeTargetBox::renderTargetWeapon(object *target_objp)
|
||||
|
||||
break;
|
||||
case 1:
|
||||
model_set_outline_color_fast(iff_get_color_by_team_and_object(target_team, Player_ship->team, 0, target_objp));
|
||||
render_info.set_outline_color(*iff_get_color_by_team_and_object(target_team, Player_ship->team, 0, target_objp));
|
||||
|
||||
flags = (Cmdline_nohtl) ? MR_SHOW_OUTLINE : MR_SHOW_OUTLINE_HTL;
|
||||
flags |= MR_NO_POLYS | MR_NO_LIGHTING;
|
||||
flags |= MR_NO_POLYS | MR_NO_LIGHTING | MR_NO_TEXTURING;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
model_set_outline_color_fast(iff_get_color_by_team_and_object(target_team, Player_ship->team, 0, target_objp));
|
||||
render_info.set_outline_color(*iff_get_color_by_team_and_object(target_team, Player_ship->team, 0, target_objp));
|
||||
|
||||
flags |= MR_NO_LIGHTING | MR_NO_TEXTURING;
|
||||
|
||||
@@ -918,25 +927,25 @@ void HudGaugeTargetBox::renderTargetWeapon(object *target_objp)
|
||||
break;
|
||||
case 1:
|
||||
if (ship_is_tagged(viewed_obj))
|
||||
model_set_outline_color_fast(iff_get_color(IFF_COLOR_TAGGED, 1));
|
||||
render_info.set_outline_color(*iff_get_color(IFF_COLOR_TAGGED, 1));
|
||||
else
|
||||
model_set_outline_color_fast(iff_get_color_by_team_and_object(homing_shipp->team, Player_ship->team, 1, viewed_obj));
|
||||
render_info.set_outline_color(*iff_get_color_by_team_and_object(homing_shipp->team, Player_ship->team, 1, viewed_obj));
|
||||
|
||||
if (homing_sip->uses_team_colors) {
|
||||
gr_set_team_color(homing_shipp->team_name, homing_shipp->secondary_team_name, homing_shipp->team_change_timestamp, homing_shipp->team_change_time);
|
||||
render_info.set_team_color(homing_shipp->team_name, homing_shipp->secondary_team_name, homing_shipp->team_change_timestamp, homing_shipp->team_change_time);
|
||||
}
|
||||
|
||||
flags = (Cmdline_nohtl) ? MR_SHOW_OUTLINE : MR_SHOW_OUTLINE_HTL;
|
||||
flags |= MR_NO_POLYS | MR_NO_LIGHTING;
|
||||
flags |= MR_NO_POLYS | MR_NO_LIGHTING | MR_NO_TEXTURING;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
if (ship_is_tagged(viewed_obj))
|
||||
model_set_outline_color_fast(iff_get_color(IFF_COLOR_TAGGED, 1));
|
||||
render_info.set_outline_color(*iff_get_color(IFF_COLOR_TAGGED, 1));
|
||||
else
|
||||
model_set_outline_color_fast(iff_get_color_by_team_and_object(homing_shipp->team, Player_ship->team, 1, viewed_obj));
|
||||
render_info.set_outline_color(*iff_get_color_by_team_and_object(homing_shipp->team, Player_ship->team, 1, viewed_obj));
|
||||
|
||||
flags |= MR_NO_LIGHTING | MR_NO_TEXTURING;
|
||||
|
||||
@@ -945,20 +954,20 @@ void HudGaugeTargetBox::renderTargetWeapon(object *target_objp)
|
||||
}
|
||||
|
||||
if (hud_target_lod >= 0) {
|
||||
model_set_detail_level(hud_target_lod);
|
||||
render_info.set_detail_level_lock(hud_target_lod);
|
||||
}
|
||||
|
||||
if(Targetbox_shader_effect > -1) {
|
||||
flags |= MR_ANIMATED_SHADER;
|
||||
|
||||
opengl_shader_set_animated_effect(Targetbox_shader_effect);
|
||||
render_info.set_animated_effect(Targetbox_shader_effect, 0.0f);
|
||||
}
|
||||
|
||||
if ( Monitor_mask >= 0 ) {
|
||||
gr_stencil_set(GR_STENCIL_READ);
|
||||
}
|
||||
|
||||
Interp_desaturate = Desaturated;
|
||||
if ( Desaturated ) {
|
||||
flags |= MR_DESATURATED;
|
||||
}
|
||||
|
||||
if (missile_view == TRUE) {
|
||||
if (!Glowpoint_override)
|
||||
@@ -972,23 +981,29 @@ void HudGaugeTargetBox::renderTargetWeapon(object *target_objp)
|
||||
}
|
||||
|
||||
if (missile_view == FALSE ) {
|
||||
model_render( viewed_model_num, &viewed_obj->orient, &obj_pos, flags | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_IS_MISSILE | MR_NO_FOGGING, -1, -1, replacement_textures);
|
||||
render_info.set_flags(flags | MR_AUTOCENTER | MR_IS_MISSILE | MR_NO_FOGGING);
|
||||
render_info.set_replacement_textures(replacement_textures);
|
||||
|
||||
model_render_immediate( &render_info, viewed_model_num, &viewed_obj->orient, &obj_pos );
|
||||
} else {
|
||||
// maybe render a special hud-target-only model
|
||||
// autocentering is bad in this one
|
||||
if(homing_sip->model_num_hud >= 0){
|
||||
model_render( homing_sip->model_num_hud, &viewed_obj->orient, &obj_pos, flags | MR_LOCK_DETAIL | MR_NO_FOGGING);
|
||||
render_info.set_flags(flags | MR_NO_FOGGING);
|
||||
|
||||
model_render_immediate( &render_info, homing_sip->model_num_hud, &viewed_obj->orient, &obj_pos);
|
||||
} else {
|
||||
model_render( homing_sip->model_num, &viewed_obj->orient, &obj_pos, flags | MR_LOCK_DETAIL | MR_NO_FOGGING, -1, -1, homing_shipp->ship_replacement_textures);
|
||||
render_info.set_flags(flags | MR_NO_FOGGING);
|
||||
render_info.set_replacement_textures(homing_shipp->ship_replacement_textures);
|
||||
|
||||
model_render_immediate( &render_info, homing_sip->model_num, &viewed_obj->orient, &obj_pos );
|
||||
}
|
||||
}
|
||||
|
||||
Interp_desaturate = false;
|
||||
if (missile_view == TRUE) {
|
||||
Glowpoint_override = false;
|
||||
|
||||
ship_model_stop( viewed_obj );
|
||||
gr_disable_team_color();
|
||||
}
|
||||
|
||||
if ( Monitor_mask >= 0 ) {
|
||||
@@ -1083,6 +1098,8 @@ void HudGaugeTargetBox::renderTargetAsteroid(object *target_objp)
|
||||
renderTargetSetup(&camera_eye, &camera_orient, 0.5f);
|
||||
model_clear_instance(Asteroid_info[asteroidp->asteroid_type].model_num[pof]);
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
switch (Targetbox_wire) {
|
||||
case 0:
|
||||
flags |= MR_NO_LIGHTING;
|
||||
@@ -1090,21 +1107,21 @@ void HudGaugeTargetBox::renderTargetAsteroid(object *target_objp)
|
||||
break;
|
||||
case 1:
|
||||
if (time_to_impact>=0)
|
||||
model_set_outline_color(255,255,255);
|
||||
render_info.set_outline_color(255,255,255);
|
||||
else
|
||||
model_set_outline_color(64,64,0);
|
||||
render_info.set_outline_color(64,64,0);
|
||||
|
||||
flags = (Cmdline_nohtl) ? MR_SHOW_OUTLINE : MR_SHOW_OUTLINE_HTL;
|
||||
flags |= MR_NO_POLYS | MR_NO_LIGHTING;
|
||||
flags |= MR_NO_POLYS | MR_NO_LIGHTING | MR_NO_TEXTURING;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
if (time_to_impact>=0)
|
||||
model_set_outline_color(255,255,255);
|
||||
render_info.set_outline_color(255,255,255);
|
||||
else
|
||||
model_set_outline_color(64,64,0);
|
||||
render_info.set_outline_color(64,64,0);
|
||||
|
||||
flags |= MR_NO_LIGHTING | MR_NO_TEXTURING;
|
||||
|
||||
@@ -1112,20 +1129,20 @@ void HudGaugeTargetBox::renderTargetAsteroid(object *target_objp)
|
||||
}
|
||||
|
||||
if(Targetbox_shader_effect > -1) {
|
||||
flags |= MR_ANIMATED_SHADER;
|
||||
|
||||
opengl_shader_set_animated_effect(Targetbox_shader_effect);
|
||||
render_info.set_animated_effect(Targetbox_shader_effect, 0.0f);
|
||||
}
|
||||
|
||||
if ( Monitor_mask >= 0 ) {
|
||||
gr_stencil_set(GR_STENCIL_READ);
|
||||
}
|
||||
|
||||
Interp_desaturate = Desaturated;
|
||||
if ( Desaturated ) {
|
||||
flags |= MR_DESATURATED;
|
||||
}
|
||||
|
||||
model_render(Asteroid_info[asteroidp->asteroid_type].model_num[pof], &target_objp->orient, &obj_pos, flags | MR_LOCK_DETAIL | MR_NO_FOGGING );
|
||||
render_info.set_flags(flags | MR_NO_FOGGING);
|
||||
|
||||
Interp_desaturate = false;
|
||||
model_render_immediate( &render_info, Asteroid_info[asteroidp->asteroid_type].model_num[pof], &target_objp->orient, &obj_pos );
|
||||
|
||||
if ( Monitor_mask >= 0 ) {
|
||||
gr_stencil_set(GR_STENCIL_NONE);
|
||||
|
||||
+54
-1
@@ -11,6 +11,9 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <SDL_timer.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
@@ -34,10 +37,15 @@ static longlong Timer_last_value = 0, Timer_base = 0, Timer_freq = 0;
|
||||
static const int precision = 1;
|
||||
#endif
|
||||
|
||||
static longlong Timer_perf_counter_base = 0; // perf counter start time
|
||||
static longlong Timer_perf_counter_freq = 0; // perf counter frequency - number of ticks per second
|
||||
|
||||
static int Timer_inited = 0;
|
||||
|
||||
static CRITICAL_SECTION Timer_lock;
|
||||
|
||||
#define MICROSECONDS_PER_SECOND 1000000
|
||||
|
||||
void timer_close()
|
||||
{
|
||||
if ( Timer_inited ) {
|
||||
@@ -57,6 +65,26 @@ void timer_init()
|
||||
#ifdef _WIN32
|
||||
timeBeginPeriod(precision);
|
||||
Timer_base = Timer_last_value = timeGetTime();
|
||||
|
||||
// get the performance counter start time
|
||||
LARGE_INTEGER perf_start_time;
|
||||
QueryPerformanceCounter(&perf_start_time);
|
||||
Timer_perf_counter_base = perf_start_time.QuadPart;
|
||||
|
||||
// get the performance counter's ticks per second frequency
|
||||
LARGE_INTEGER perf_frequency;
|
||||
QueryPerformanceFrequency(&perf_frequency);
|
||||
Timer_perf_counter_freq = perf_frequency.QuadPart;
|
||||
#else
|
||||
timeval time_value;
|
||||
|
||||
// get the performance counter start time
|
||||
gettimeofday(&time_value, NULL);
|
||||
|
||||
Timer_perf_counter_base = time_value.tv_sec * MICROSECONDS_PER_SECOND + time_value.tv_usec;
|
||||
|
||||
// get the performance counter's ticks per second frequency
|
||||
Timer_perf_counter_freq = 1;
|
||||
#endif
|
||||
|
||||
Timer_inited = 1;
|
||||
@@ -90,7 +118,6 @@ static uint timer_get()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
fix timer_get_fixed_seconds()
|
||||
{
|
||||
if (!Timer_inited) {
|
||||
@@ -145,6 +172,32 @@ int timer_get_microseconds()
|
||||
return timer_get() * 1000;
|
||||
}
|
||||
|
||||
uint timer_get_high_res_microseconds()
|
||||
{
|
||||
if ( !Timer_inited ) {
|
||||
Int3();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
ENTER_CRITICAL_SECTION( Timer_lock);
|
||||
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter(&time);
|
||||
longlong elapsed = time.QuadPart;// - Timer_perf_counter_base;
|
||||
|
||||
LEAVE_CRITICAL_SECTION( Timer_lock);
|
||||
|
||||
return (uint)(elapsed * MICROSECONDS_PER_SECOND / Timer_perf_counter_freq);
|
||||
#else
|
||||
timeval time_value;
|
||||
|
||||
gettimeofday(&time_value, NULL);
|
||||
|
||||
return time_value.tv_sec * MICROSECONDS_PER_SECOND + time_value.tv_usec;// - Timer_perf_counter_base);
|
||||
#endif
|
||||
}
|
||||
|
||||
// 0 means invalid,
|
||||
// 1 means always return true
|
||||
// 2 and above actually check the time
|
||||
|
||||
@@ -44,6 +44,7 @@ extern fix timer_get_fixed_secondsX(); // Assume interrupts already disabled
|
||||
extern fix timer_get_approx_seconds(); // Returns time since program started... accurate to 1/120th of a second
|
||||
extern int timer_get_milliseconds(); //
|
||||
extern int timer_get_microseconds();
|
||||
extern uint timer_get_high_res_microseconds();
|
||||
extern int timer_get_seconds(); // seconds since program started... not accurate, but good for long
|
||||
// runtimes with second-based timeouts
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "jumpnode/jumpnode.h"
|
||||
#include "model/model.h"
|
||||
#include "hud/hud.h"
|
||||
#include "model/modelrender.h"
|
||||
|
||||
SCP_list<CJumpNode> Jump_nodes;
|
||||
|
||||
@@ -245,7 +246,7 @@ bool CJumpNode::IsSpecialModel()
|
||||
* @param pos World position
|
||||
* @param view_pos Viewer's world position, can be NULL
|
||||
*/
|
||||
void CJumpNode::Render(vec3d *pos, vec3d *view_pos)
|
||||
void CJumpNode::RenderDEPRECATED(vec3d *pos, vec3d *view_pos)
|
||||
{
|
||||
Assert(pos != NULL);
|
||||
// Assert(view_pos != NULL); - view_pos can be NULL
|
||||
@@ -258,14 +259,14 @@ void CJumpNode::Render(vec3d *pos, vec3d *view_pos)
|
||||
|
||||
matrix node_orient = IDENTITY_MATRIX;
|
||||
|
||||
int mr_flags = MR_NO_LIGHTING | MR_LOCK_DETAIL;
|
||||
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(m_modelnum, &node_orient, pos, mr_flags );
|
||||
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);
|
||||
@@ -296,11 +297,86 @@ void CJumpNode::Render(vec3d *pos, vec3d *view_pos)
|
||||
gr_set_color(HUD_color_red, HUD_color_green, HUD_color_blue);
|
||||
}
|
||||
|
||||
model_render(m_modelnum, &node_orient, pos, mr_flags );
|
||||
model_render_DEPRECATED(m_modelnum, &node_orient, pos, mr_flags );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CJumpNode::Render(vec3d *pos, vec3d *view_pos)
|
||||
{
|
||||
draw_list scene;
|
||||
|
||||
Render(&scene, pos, view_pos);
|
||||
|
||||
scene.render_all();
|
||||
|
||||
gr_set_fill_mode(GR_FILL_MODE_SOLID);
|
||||
gr_clear_states();
|
||||
gr_set_buffer(-1);
|
||||
}
|
||||
|
||||
void CJumpNode::Render(draw_list* scene, 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 | MR_NO_BATCH;
|
||||
if(!(m_flags & JN_SHOW_POLYS)) {
|
||||
mr_flags |= MR_NO_CULL | MR_NO_POLYS | MR_SHOW_OUTLINE | MR_SHOW_OUTLINE_HTL | MR_NO_TEXTURING;
|
||||
}
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
render_info.set_detail_level_lock(0);
|
||||
render_info.set_flags(mr_flags);
|
||||
|
||||
if ( Fred_running ) {
|
||||
render_info.set_outline_color(m_display_color);
|
||||
|
||||
model_render_queue(&render_info, scene, m_modelnum, &node_orient, pos);
|
||||
} else {
|
||||
if (m_flags & JN_USE_DISPLAY_COLOR) {
|
||||
//gr_set_color_fast(&m_display_color);
|
||||
render_info.set_outline_color(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;
|
||||
}
|
||||
}
|
||||
|
||||
render_info.set_outline_color(HUD_color_defaults[alpha_index]);
|
||||
} else {
|
||||
render_info.set_outline_color(HUD_color_red, HUD_color_green, HUD_color_blue);
|
||||
}
|
||||
|
||||
model_render_queue(&render_info, scene, m_modelnum, &node_orient, pos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jump node by given name
|
||||
*
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
struct vec3d;
|
||||
class object;
|
||||
|
||||
class draw_list;
|
||||
|
||||
//Jump node flags
|
||||
#define JN_USE_DISPLAY_COLOR (1<<0) //Use display_color instead of HUD color
|
||||
#define JN_SHOW_POLYS (1<<1) //Display model normally, rather than as wireframe
|
||||
@@ -66,7 +68,9 @@ public:
|
||||
bool IsSpecialModel();
|
||||
|
||||
//Rendering
|
||||
void Render(vec3d *pos, vec3d *view_pos = NULL);
|
||||
void RenderDEPRECATED(vec3d *pos, vec3d *view_pos = NULL);
|
||||
void Render(vec3d *pos, vec3d *view_pos = NULL);
|
||||
void Render(draw_list *scene, vec3d *pos, vec3d *view_pos = NULL);
|
||||
};
|
||||
|
||||
//-----Globals------
|
||||
|
||||
+152
-43
@@ -30,6 +30,8 @@
|
||||
#include "graphics/gropenglshader.h"
|
||||
#include "graphics/gropengldraw.h"
|
||||
#include "hud/hudshield.h"
|
||||
#include "graphics/gropengllight.h"
|
||||
#include "graphics/shadows.h"
|
||||
|
||||
// flags
|
||||
#define LAB_FLAG_NORMAL (0) // default
|
||||
@@ -38,7 +40,7 @@
|
||||
#define LAB_FLAG_SHOW_DEBRIS (1<<2) // render debris instead of normal LOD
|
||||
#define LAB_FLAG_SUBMODEL_ROTATE (1<<3) // do rotation for any rotating ship subobjects
|
||||
#define LAB_FLAG_LIGHTNING_ARCS (1<<4) // show damage lightning
|
||||
#define LAB_FLAG_FULLY_LOAD (1<<5) // use create_ship() to test the ships
|
||||
#define LAB_FLAG_UNUSED (1<<5) // feel free to change that to something you need - Valathil
|
||||
#define LAB_FLAG_SHOW_WEAPONS (1<<6) // determines if external weapons models are displayed
|
||||
#define LAB_FLAG_INITIAL_ROTATION (1<<7) // initial rotation setting
|
||||
|
||||
@@ -70,12 +72,14 @@ static int Lab_insignia_index = -1;
|
||||
static ubyte Lab_mode = LAB_MODE_NONE;
|
||||
static int Lab_selected_index = -1;
|
||||
static int Lab_last_selected_ship = -1;
|
||||
static int Lab_selected_object = -1;
|
||||
static int Lab_last_selected_weapon = -1;
|
||||
|
||||
static int Lab_model_num = -1;
|
||||
static int Lab_weaponmodel_num[MAX_SHIP_WEAPONS];
|
||||
static int Lab_model_LOD = 0;
|
||||
static int Lab_model_flags = MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING;
|
||||
static int Lab_model_flags = MR_AUTOCENTER | MR_NO_FOGGING;
|
||||
static int Lab_model_debug_flags = 0;
|
||||
static char Lab_model_filename[MAX_FILENAME_LEN];
|
||||
static char Lab_weaponmodel_filename[MAX_SHIP_WEAPONS][MAX_FILENAME_LEN];
|
||||
|
||||
@@ -532,7 +536,7 @@ void labviewer_add_model_arcs()
|
||||
}
|
||||
}
|
||||
|
||||
void labviewer_add_model_thrusters(ship_info *sip)
|
||||
void labviewer_add_model_thrusters(model_render_params *render_info, ship_info *sip)
|
||||
{
|
||||
static float thruster_frame = 0.0f;
|
||||
static float thruster_glow_frame = 0.0f;
|
||||
@@ -685,7 +689,7 @@ void labviewer_add_model_thrusters(ship_info *sip)
|
||||
|
||||
mst.use_ab = Lab_thrust_afterburn;
|
||||
mst.glow_noise = thruster_glow_noise;
|
||||
mst.rotvel = &vmd_zero_vector;
|
||||
mst.rotvel = vmd_zero_vector;
|
||||
|
||||
if (Lab_mode == LAB_MODE_SHIP) {
|
||||
mst.glow_rad_factor = sip->thruster01_glow_rad_factor;
|
||||
@@ -702,9 +706,11 @@ void labviewer_add_model_thrusters(ship_info *sip)
|
||||
}
|
||||
|
||||
// set, and go...
|
||||
model_set_thrust(Lab_model_num, &mst);
|
||||
render_info->set_thruster_info(mst);
|
||||
}
|
||||
|
||||
void light_set_all_relevent();
|
||||
|
||||
void labviewer_render_model(float frametime)
|
||||
{
|
||||
int i, j;
|
||||
@@ -716,6 +722,9 @@ void labviewer_render_model(float frametime)
|
||||
sip = &Ship_info[Lab_selected_index];
|
||||
}
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
model_clear_instance(Lab_model_num);
|
||||
|
||||
// get correct revolution rate
|
||||
rev_rate = REVOLUTION_RATE;
|
||||
@@ -728,7 +737,7 @@ void labviewer_render_model(float frametime)
|
||||
}
|
||||
|
||||
if (sip->uses_team_colors && !Teamcolor_override) {
|
||||
gr_set_team_color(Lab_team_color, "none", 0, 0);
|
||||
render_info.set_team_color(Lab_team_color, "none", 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,41 +824,55 @@ void labviewer_render_model(float frametime)
|
||||
g3_set_view_matrix(&Lab_viewer_pos, &vmd_identity_matrix, Lab_viewer_zoom);
|
||||
}
|
||||
|
||||
if (!Cmdline_nohtl) {
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, 1.0f, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
}
|
||||
|
||||
|
||||
// lighting for techroom
|
||||
light_reset();
|
||||
vec3d light_dir = vmd_zero_vector;
|
||||
light_dir.xyz.y = 1.0f;
|
||||
light_add_directional(&light_dir, 0.65f, 1.0f, 1.0f, 1.0f);
|
||||
light_dir.xyz.x = 0.0000001f;
|
||||
light_add_directional(&light_dir, 0.65f, 1.0f, 1.0f, 1.0f,-1);
|
||||
int mx, my;
|
||||
mouse_get_pos( &mx, &my );
|
||||
light_dir.xyz.y = 0.0000001f;
|
||||
light_dir.xyz.x = sin(my/150.0f);
|
||||
light_dir.xyz.z = cos(my/150.0f);
|
||||
vm_vec_normalize(&light_dir);
|
||||
vm_vec_scale(&light_dir, mx*10.1f);
|
||||
light_add_point(&light_dir,1,mx*10.2f+0.1f, 0.5f, 1.0f, 1.0f, 1.0f,-1);
|
||||
|
||||
light_rotate_all();
|
||||
// lighting for techroom
|
||||
|
||||
model_set_outline_color(255, 255, 255);
|
||||
model_clear_instance(Lab_model_num);
|
||||
model_set_detail_level(Lab_model_LOD);
|
||||
render_info.set_outline_color(255, 255, 255);
|
||||
render_info.set_detail_level_lock(Lab_model_LOD);
|
||||
|
||||
int flagggs = Lab_model_flags;
|
||||
|
||||
// only render the insignia when the flag is set
|
||||
if (Lab_viewer_flags & LAB_FLAG_SHOW_INSIGNIA) {
|
||||
model_set_insignia_bitmap(Lab_insignia_bitmap);
|
||||
render_info.set_insignia_bitmap(Lab_insignia_bitmap);
|
||||
}
|
||||
|
||||
// render special if we are showing debris
|
||||
if (Lab_viewer_flags & LAB_FLAG_SHOW_DEBRIS) {
|
||||
polymodel *pm = model_get(Lab_model_num);
|
||||
|
||||
if (!Cmdline_nohtl) {
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, 1.0f, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
}
|
||||
|
||||
for (i = 0; i < pm->num_debris_objects; i++) {
|
||||
vec3d world_point = ZERO_VECTOR;
|
||||
|
||||
model_find_world_point(&world_point, &pm->submodel[pm->debris_objects[i]].offset, Lab_model_num, -1, &Lab_viewer_orient, &vmd_zero_vector);
|
||||
|
||||
submodel_render(Lab_model_num, pm->debris_objects[i], &Lab_viewer_orient, &world_point, Lab_model_flags, -1);
|
||||
Shadow_override = true;
|
||||
|
||||
render_info.set_flags(Lab_model_flags);
|
||||
|
||||
submodel_render_immediate(&render_info, Lab_model_num, pm->debris_objects[i], &Lab_viewer_orient, &world_point);
|
||||
Shadow_override = false;
|
||||
}
|
||||
}
|
||||
// render normally otherwise
|
||||
@@ -861,7 +884,7 @@ void labviewer_render_model(float frametime)
|
||||
|
||||
// ship/weapon thrusters
|
||||
if (Lab_model_flags & MR_SHOW_THRUSTERS) {
|
||||
labviewer_add_model_thrusters(sip);
|
||||
labviewer_add_model_thrusters(&render_info, sip);
|
||||
}
|
||||
|
||||
// do initial rotation
|
||||
@@ -893,7 +916,7 @@ void labviewer_render_model(float frametime)
|
||||
if ( !(Lab_ship_model_subsys[i].flags & MSS_FLAG_ROTATES) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
model_set_instance(Lab_model_num, Lab_ship_model_subsys[i].subobj_num, &Lab_ship_subsys[i].submodel_info_1 );
|
||||
|
||||
// if we got this far, we can rotate - so choose which method to use
|
||||
@@ -904,8 +927,81 @@ void labviewer_render_model(float frametime)
|
||||
}
|
||||
}
|
||||
}
|
||||
opengl_shader_set_animated_effect(ANIMATED_SHADER_LOADOUTSELECT_FS1);
|
||||
opengl_shader_set_animated_timer(MIN((timer_get_milliseconds()-anim_timer_start)/1500.0f,2.0f));
|
||||
|
||||
if( !( flagggs & MR_NO_LIGHTING ) && Cmdline_shadow_quality ) {
|
||||
polymodel *pm = model_get(Lab_model_num);
|
||||
|
||||
shadows_start_render(&Eye_matrix, &Eye_position, Proj_fov, gr_screen.clip_aspect, -Lab_viewer_pos.xyz.z + pm->rad, -Lab_viewer_pos.xyz.z + pm->rad + 200.0f, -Lab_viewer_pos.xyz.z + pm->rad + 2000.0f, -Lab_viewer_pos.xyz.z + pm->rad + 10000.0f);
|
||||
|
||||
render_info.set_flags(MR_NO_TEXTURING | MR_NO_LIGHTING | MR_AUTOCENTER);
|
||||
|
||||
model_render_immediate(&render_info, Lab_model_num, &Lab_viewer_orient, &vmd_zero_vector);
|
||||
|
||||
//render weapon models if selected
|
||||
if ( Lab_mode == LAB_MODE_SHIP && ( Lab_viewer_flags & LAB_FLAG_SHOW_WEAPONS ) ) {
|
||||
int j,k,l;
|
||||
g3_start_instance_matrix(&vmd_zero_vector, &Lab_viewer_orient, true);
|
||||
l = 0;
|
||||
|
||||
// no thrusters for attached missiles
|
||||
int render_flags = MR_NO_TEXTURING | MR_NO_LIGHTING;
|
||||
|
||||
//primary weapons
|
||||
for (j = 0; j < sip->num_primary_banks; j++) {
|
||||
if (!sip->draw_primary_models[j])
|
||||
continue;
|
||||
if (Lab_weaponmodel_num[l] >= 0) {
|
||||
w_bank *bank = &model_get(Lab_model_num)->gun_banks[j];
|
||||
for(k = 0; k < bank->num_slots; k++) {
|
||||
|
||||
render_info.set_flags(render_flags);
|
||||
model_render_immediate(&render_info, Lab_weaponmodel_num[l], &vmd_identity_matrix, &bank->pnt[k]);
|
||||
}
|
||||
}
|
||||
l++;
|
||||
}
|
||||
//secondary weapons
|
||||
vec3d secondary_weapon_pos;
|
||||
w_bank* bank;
|
||||
|
||||
for (j = 0; j < sip->num_secondary_banks; j++) {
|
||||
if (!sip->draw_secondary_models[j])
|
||||
continue;
|
||||
if (Lab_weaponmodel_num[l] >= 0) {
|
||||
bank = &(model_get(Lab_model_num))->missile_banks[j];
|
||||
if (Weapon_info[sip->secondary_bank_weapons[j]].wi_flags2 & WIF2_EXTERNAL_WEAPON_LNCH) {
|
||||
for(k = 0; k < bank->num_slots; k++) {
|
||||
render_info.set_flags(render_flags);
|
||||
model_render_immediate(&render_info, Lab_weaponmodel_num[l], &vmd_identity_matrix, &bank->pnt[k]);
|
||||
}
|
||||
} else {
|
||||
for(k = 0; k < bank->num_slots; k++)
|
||||
{
|
||||
secondary_weapon_pos = bank->pnt[k];
|
||||
render_info.set_flags(render_flags);
|
||||
model_render_immediate(&render_info, Lab_weaponmodel_num[l], &vmd_identity_matrix, &secondary_weapon_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
l++;
|
||||
}
|
||||
g3_done_instance(true);
|
||||
}
|
||||
|
||||
shadows_end_render();
|
||||
}
|
||||
|
||||
if (!Cmdline_nohtl) {
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, 1.0f, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
}
|
||||
|
||||
gr_opengl_deferred_lighting_begin();
|
||||
|
||||
// render_info.set_animated_effect(
|
||||
// ANIMATED_SHADER_LOADOUTSELECT_FS1,
|
||||
// MIN((timer_get_milliseconds()-anim_timer_start)/1500.0f, 2.0f)
|
||||
// );
|
||||
|
||||
//render weapon models if selected
|
||||
if (Lab_mode == LAB_MODE_SHIP && (Lab_viewer_flags & LAB_FLAG_SHOW_WEAPONS)) {
|
||||
@@ -924,7 +1020,8 @@ void labviewer_render_model(float frametime)
|
||||
if (Lab_weaponmodel_num[l] >= 0) {
|
||||
w_bank *bank = &model_get(Lab_model_num)->gun_banks[j];
|
||||
for(k = 0; k < bank->num_slots; k++) {
|
||||
model_render(Lab_weaponmodel_num[l], &vmd_identity_matrix, &bank->pnt[k], render_flags);
|
||||
render_info.set_flags(render_flags);
|
||||
model_render_immediate(&render_info, Lab_weaponmodel_num[l], &vmd_identity_matrix, &bank->pnt[k]);
|
||||
}
|
||||
}
|
||||
l++;
|
||||
@@ -940,13 +1037,15 @@ void labviewer_render_model(float frametime)
|
||||
bank = &(model_get(Lab_model_num))->missile_banks[j];
|
||||
if (Weapon_info[sip->secondary_bank_weapons[j]].wi_flags2 & WIF2_EXTERNAL_WEAPON_LNCH) {
|
||||
for(k = 0; k < bank->num_slots; k++) {
|
||||
model_render(Lab_weaponmodel_num[l], &vmd_identity_matrix, &bank->pnt[k], render_flags);
|
||||
render_info.set_flags(render_flags);
|
||||
model_render_immediate(&render_info, Lab_weaponmodel_num[l], &vmd_identity_matrix, &bank->pnt[k]);
|
||||
}
|
||||
} else {
|
||||
for(k = 0; k < bank->num_slots; k++)
|
||||
{
|
||||
secondary_weapon_pos = bank->pnt[k];
|
||||
model_render(Lab_weaponmodel_num[l], &vmd_identity_matrix, &secondary_weapon_pos, render_flags);
|
||||
render_info.set_flags(render_flags);
|
||||
model_render_immediate(&render_info, Lab_weaponmodel_num[l], &vmd_identity_matrix, &secondary_weapon_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -954,17 +1053,27 @@ void labviewer_render_model(float frametime)
|
||||
}
|
||||
g3_done_instance(true);
|
||||
}
|
||||
model_render(Lab_model_num, &Lab_viewer_orient, &vmd_zero_vector, /*Lab_model_flags*/flagggs, -1, -1);
|
||||
|
||||
render_info.set_flags(flagggs);
|
||||
render_info.set_object_number(Lab_selected_object);
|
||||
|
||||
model_render_immediate(&render_info, Lab_model_num, &Lab_viewer_orient, &vmd_zero_vector, MODEL_RENDER_OPAQUE);
|
||||
gr_opengl_deferred_lighting_end();
|
||||
gr_opengl_deferred_lighting_finish();
|
||||
bool gpo_save = Glowpoint_override;
|
||||
Glowpoint_override = true;
|
||||
model_render_immediate(&render_info, Lab_model_num, &Lab_viewer_orient, &vmd_zero_vector, MODEL_RENDER_TRANS);
|
||||
Glowpoint_override = gpo_save;
|
||||
}
|
||||
|
||||
batch_render_all();
|
||||
|
||||
gr_copy_effect_texture();
|
||||
batch_render_distortion_map_bitmaps();
|
||||
if ( !Cmdline_nohtl ) {
|
||||
gr_end_view_matrix();
|
||||
gr_end_proj_matrix();
|
||||
}
|
||||
|
||||
gr_disable_team_color();
|
||||
g3_end_frame();
|
||||
}
|
||||
|
||||
@@ -1221,6 +1330,9 @@ void labviewer_do_render(float frametime)
|
||||
|
||||
void labviewer_exit(Button *caller)
|
||||
{
|
||||
if(Lab_selected_object != -1) {
|
||||
obj_delete(Lab_selected_object);
|
||||
}
|
||||
gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
|
||||
}
|
||||
|
||||
@@ -1807,7 +1919,6 @@ void labviewer_make_render_options_window(Button *caller)
|
||||
// add all of the flags that we want/need...
|
||||
|
||||
// viewer flags
|
||||
ADD_RENDER_FLAG("Test Load Ships", Lab_viewer_flags, LAB_FLAG_FULLY_LOAD);
|
||||
ADD_RENDER_FLAG("Disable Model Rotation", Lab_viewer_flags, LAB_FLAG_NO_ROTATION);
|
||||
ADD_RENDER_FLAG("Show Insignia", Lab_viewer_flags, LAB_FLAG_SHOW_INSIGNIA);
|
||||
ADD_RENDER_FLAG("Show Damage Lightning", Lab_viewer_flags, LAB_FLAG_LIGHTNING_ARCS);
|
||||
@@ -1839,24 +1950,22 @@ void labviewer_make_render_options_window(Button *caller)
|
||||
ADD_RENDER_BOOL("No Team Colors", Teamcolor_override);
|
||||
ADD_RENDER_BOOL("No Glow Points", Glowpoint_override);
|
||||
// model flags
|
||||
ADD_RENDER_FLAG("Wireframe", Lab_model_flags, ((Cmdline_nohtl) ? MR_SHOW_OUTLINE : MR_SHOW_OUTLINE_HTL) | MR_NO_POLYS);
|
||||
ADD_RENDER_FLAG("Wireframe", Lab_model_flags, ((Cmdline_nohtl) ? MR_SHOW_OUTLINE | MR_NO_POLYS | MR_NO_TEXTURING : MR_SHOW_OUTLINE_HTL | MR_NO_POLYS | MR_NO_TEXTURING) );
|
||||
ADD_RENDER_FLAG("Transparent", Lab_model_flags, MR_ALL_XPARENT);
|
||||
ADD_RENDER_FLAG("No Lighting", Lab_model_flags, MR_NO_LIGHTING);
|
||||
ADD_RENDER_FLAG("No Z-Buffer", Lab_model_flags, MR_NO_ZBUFFER);
|
||||
ADD_RENDER_FLAG("No Culling", Lab_model_flags, MR_NO_CULL);
|
||||
ADD_RENDER_FLAG("Force Clamp", Lab_model_flags, MR_FORCE_CLAMP);
|
||||
ADD_RENDER_FLAG("Show Full Detail", Lab_model_flags, MR_FULL_DETAIL);
|
||||
ADD_RENDER_FLAG("Show Pivots", Lab_model_flags, MR_SHOW_PIVOTS);
|
||||
ADD_RENDER_FLAG("Show Paths", Lab_model_flags, MR_SHOW_PATHS);
|
||||
ADD_RENDER_FLAG("Show Bay Paths", Lab_model_flags, MR_BAY_PATHS);
|
||||
ADD_RENDER_FLAG("Show Radius", Lab_model_flags, MR_SHOW_RADIUS);
|
||||
ADD_RENDER_FLAG("Show Shields", Lab_model_flags, MR_SHOW_SHIELDS);
|
||||
ADD_RENDER_FLAG("Show Pivots", Lab_model_debug_flags, MR_DEBUG_PIVOTS);
|
||||
ADD_RENDER_FLAG("Show Paths", Lab_model_debug_flags, MR_DEBUG_PATHS);
|
||||
ADD_RENDER_FLAG("Show Bay Paths", Lab_model_debug_flags, MR_DEBUG_BAY_PATHS);
|
||||
ADD_RENDER_FLAG("Show Radius", Lab_model_debug_flags, MR_DEBUG_RADIUS);
|
||||
ADD_RENDER_FLAG("Show Shields", Lab_model_debug_flags, MR_DEBUG_SHIELDS);
|
||||
ADD_RENDER_FLAG("Show Thrusters", Lab_model_flags, MR_SHOW_THRUSTERS);
|
||||
ADD_RENDER_FLAG("Animated Shader", Lab_model_flags, MR_ANIMATED_SHADER);
|
||||
ADD_RENDER_FLAG("Show Ship Weapons", Lab_viewer_flags, LAB_FLAG_SHOW_WEAPONS);
|
||||
ADD_RENDER_FLAG("Initial Rotation", Lab_viewer_flags, LAB_FLAG_INITIAL_ROTATION);
|
||||
|
||||
|
||||
// start tree
|
||||
cmp = (Tree*)Lab_render_options_window->AddChild(new Tree("Detail Options Tree", 0, y + 2, NULL, Lab_render_options_window->GetWidth()));
|
||||
|
||||
@@ -2047,10 +2156,7 @@ void labviewer_change_ship_lod(Tree* caller)
|
||||
int ship_index = (int)(caller->GetSelectedItem()->GetParentItem()->GetData());
|
||||
Assert( ship_index >= 0 );
|
||||
|
||||
// Genghis - Attempt to create and then immediately delete the selected ship type.
|
||||
// This causes the full error-handling to kick-in, making the Lab viewer a more
|
||||
// useful tool for checking model errors.
|
||||
if (Lab_viewer_flags & LAB_FLAG_FULLY_LOAD)
|
||||
if (Lab_selected_object == -1)
|
||||
{
|
||||
// Goober5000 - The lab loads subsystems into its special lab-specific vector, but normally subsystems are loaded into the Ship_info
|
||||
// entry. Note also that models are only loaded once each. If a lab model was previously loaded using the "lightweight" method,
|
||||
@@ -2062,15 +2168,18 @@ void labviewer_change_ship_lod(Tree* caller)
|
||||
labviewer_change_bitmap();
|
||||
|
||||
The_mission.ai_profile = &Ai_profiles[Default_ai_profile];
|
||||
int test_idx = ship_create(&vmd_identity_matrix, &vmd_zero_vector, ship_index);
|
||||
obj_delete(test_idx);
|
||||
obj_snd_level_close();
|
||||
Lab_selected_object = ship_create(&vmd_identity_matrix, &vmd_zero_vector, ship_index);
|
||||
|
||||
// unload the model we just loaded
|
||||
model_page_out_textures(Ship_info[ship_index].model_num, true);
|
||||
model_unload(Ship_info[ship_index].model_num);
|
||||
Ship_info[ship_index].model_num = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj_delete(Lab_selected_object);
|
||||
Lab_selected_object = ship_create(&vmd_identity_matrix, &vmd_zero_vector, ship_index);
|
||||
}
|
||||
|
||||
Lab_last_selected_ship = Lab_selected_index;
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "model/modelrender.h"
|
||||
#include "graphics/gropengllight.h"
|
||||
#include "graphics/gropengldraw.h"
|
||||
#include "debugconsole/console.h"
|
||||
|
||||
|
||||
@@ -189,6 +192,9 @@ void light_rotate(light * l)
|
||||
}
|
||||
break;
|
||||
|
||||
case LT_CONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
Int3(); // Invalid light type
|
||||
}
|
||||
@@ -489,6 +495,9 @@ int light_filter_push( int objnum, vec3d *pos, float rad )
|
||||
}
|
||||
break;
|
||||
|
||||
case LT_CONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
Int3(); // Invalid light type
|
||||
}
|
||||
@@ -552,6 +561,9 @@ int light_filter_push_box( vec3d *min, vec3d *max )
|
||||
}
|
||||
break;
|
||||
|
||||
case LT_CONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
Int3(); // Invalid light type
|
||||
}
|
||||
@@ -639,6 +651,10 @@ void light_set_all_relevent()
|
||||
for (idx = 0; idx < (int)Static_light.size(); idx++)
|
||||
gr_set_light( Static_light[idx] );
|
||||
|
||||
extern bool Deferred_lighting;
|
||||
if(Deferred_lighting)
|
||||
return;
|
||||
|
||||
// for simplicity sake were going to forget about dynamic lights for the moment
|
||||
|
||||
int n = Num_light_levels-1;
|
||||
@@ -832,6 +848,9 @@ void light_apply_specular(ubyte *param_r, ubyte *param_g, ubyte *param_b, vec3d
|
||||
dist *= dist; // since we use radius squared
|
||||
break;
|
||||
|
||||
case LT_CONE:
|
||||
continue;
|
||||
|
||||
// others. BAD
|
||||
default:
|
||||
Int3();
|
||||
@@ -970,6 +989,12 @@ void light_apply_rgb( ubyte *param_r, ubyte *param_g, ubyte *param_b, vec3d *pos
|
||||
dist *= dist; // since we use radius squared
|
||||
break;
|
||||
|
||||
case LT_DIRECTIONAL:
|
||||
continue;
|
||||
|
||||
case LT_CONE:
|
||||
continue;
|
||||
|
||||
// others. BAD
|
||||
default:
|
||||
Int3();
|
||||
@@ -1023,3 +1048,238 @@ void light_apply_rgb( ubyte *param_r, ubyte *param_g, ubyte *param_b, vec3d *pos
|
||||
*param_g = ubyte(fl2i(gval*255.0f));
|
||||
*param_b = ubyte(fl2i(bval*255.0f));
|
||||
}
|
||||
|
||||
void light_add_cone( vec3d * pos, vec3d * dir, float angle, float inner_angle, bool dual_cone, float r1, float r2, float intensity, float r, float g, float b, int light_ignore_objnum, float spec_r, float spec_g, float spec_b, bool specular )
|
||||
{
|
||||
Assertion( r1 > 0.0f, "Invalid radius r1 specified for light: %d. Radius must be > 0.0f. Examine stack trace to determine culprit.\n", r1 );
|
||||
Assertion( r2 > 0.0f, "Invalid radius r2 specified for light: %d. Radius must be > 0.0f. Examine stack trace to determine culprit.\n", r2 );
|
||||
|
||||
if (r1 < 0.0001f || r2 < 0.0001f)
|
||||
return;
|
||||
|
||||
if(!specular){
|
||||
spec_r = r;
|
||||
spec_g = g;
|
||||
spec_b = b;
|
||||
}
|
||||
|
||||
light * l;
|
||||
|
||||
if ( Lighting_off ) return;
|
||||
|
||||
if (!Lighting_flag) return;
|
||||
|
||||
if ( Num_lights >= MAX_LIGHTS ) {
|
||||
mprintf(( "Out of lights!\n" ));
|
||||
return;
|
||||
}
|
||||
|
||||
l = &Lights[Num_lights++];
|
||||
|
||||
l->type = LT_CONE;
|
||||
l->vec = *pos;
|
||||
l->vec2= *dir;
|
||||
l->cone_angle = angle;
|
||||
l->cone_inner_angle = inner_angle;
|
||||
l->dual_cone = dual_cone;
|
||||
l->r = r;
|
||||
l->g = g;
|
||||
l->b = b;
|
||||
l->spec_r = spec_r;
|
||||
l->spec_g = spec_g;
|
||||
l->spec_b = spec_b;
|
||||
l->intensity = intensity;
|
||||
l->rada = r1;
|
||||
l->radb = r2;
|
||||
l->rada_squared = l->rada*l->rada;
|
||||
l->radb_squared = l->radb*l->radb;
|
||||
l->light_ignore_objnum = light_ignore_objnum;
|
||||
l->affected_objnum = -1;
|
||||
l->instance = Num_lights-1;
|
||||
|
||||
Assert( Num_light_levels <= 1 );
|
||||
}
|
||||
|
||||
bool light_compare_by_type(const light &a, const light &b)
|
||||
{
|
||||
return a.type < b.type;
|
||||
}
|
||||
|
||||
void scene_lights::addLight(light *light_ptr)
|
||||
{
|
||||
Assert(light_ptr != NULL);
|
||||
|
||||
AllLights.push_back(*light_ptr);
|
||||
|
||||
if ( light_ptr->type == LT_DIRECTIONAL ) {
|
||||
StaticLightIndices.push_back(AllLights.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void scene_lights::setLightFilter(int objnum, vec3d *pos, float rad)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
// clear out current filtered lights
|
||||
FilteredLights.clear();
|
||||
|
||||
if ( Deferred_lighting ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i = 0; i < AllLights.size(); ++i ) {
|
||||
light& l = AllLights[i];
|
||||
|
||||
switch ( l.type ) {
|
||||
case LT_DIRECTIONAL:
|
||||
break;
|
||||
case LT_POINT: {
|
||||
// if this is a "unique" light source, it only affects one guy
|
||||
if ( l.affected_objnum >= 0 ) {
|
||||
if ( objnum == l.affected_objnum ) {
|
||||
vec3d to_light;
|
||||
float dist_squared, max_dist_squared;
|
||||
vm_vec_sub( &to_light, &l.vec, pos );
|
||||
dist_squared = vm_vec_mag_squared(&to_light);
|
||||
|
||||
max_dist_squared = l.radb+rad;
|
||||
max_dist_squared *= max_dist_squared;
|
||||
|
||||
if ( dist_squared < max_dist_squared ) {
|
||||
FilteredLights.push_back(i);
|
||||
}
|
||||
}
|
||||
} else { // otherwise check all relevant objects
|
||||
vec3d to_light;
|
||||
float dist_squared, max_dist_squared;
|
||||
vm_vec_sub( &to_light, &l.vec, pos );
|
||||
dist_squared = vm_vec_mag_squared(&to_light);
|
||||
|
||||
max_dist_squared = l.radb+rad;
|
||||
max_dist_squared *= max_dist_squared;
|
||||
|
||||
if ( dist_squared < max_dist_squared ) {
|
||||
FilteredLights.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LT_TUBE: {
|
||||
if ( Use_GLSL > 1 ) {
|
||||
if ( l.light_ignore_objnum != objnum ) {
|
||||
vec3d nearest;
|
||||
float dist_squared, max_dist_squared;
|
||||
vm_vec_dist_squared_to_line(pos,&l.vec,&l.vec2,&nearest,&dist_squared);
|
||||
|
||||
max_dist_squared = l.radb+rad;
|
||||
max_dist_squared *= max_dist_squared;
|
||||
|
||||
if ( dist_squared < max_dist_squared ) {
|
||||
FilteredLights.push_back(i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// all tubes are "unique" light sources for now
|
||||
if ( ( l.affected_objnum >= 0 ) && ( objnum == l.affected_objnum ) ) {
|
||||
FilteredLights.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LT_CONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
light_indexing_info scene_lights::bufferLights()
|
||||
{
|
||||
size_t i;
|
||||
|
||||
light_indexing_info light_info;
|
||||
|
||||
light_info.index_start = 0;
|
||||
light_info.num_lights = 0;
|
||||
|
||||
// make sure that there are lights to bind?
|
||||
if ( FilteredLights.size() <= 0 ) {
|
||||
return light_info;
|
||||
}
|
||||
|
||||
light_info.index_start = BufferedLights.size();
|
||||
|
||||
for ( i = 0; i < FilteredLights.size(); ++i ) {
|
||||
BufferedLights.push_back(FilteredLights[i]);
|
||||
}
|
||||
|
||||
light_info.num_lights = FilteredLights.size();
|
||||
|
||||
return light_info;
|
||||
}
|
||||
|
||||
int scene_lights::getNumStaticLights()
|
||||
{
|
||||
return StaticLightIndices.size();
|
||||
}
|
||||
|
||||
void scene_lights::resetLightState()
|
||||
{
|
||||
current_light_index = -1;
|
||||
current_num_lights = -1;
|
||||
}
|
||||
|
||||
bool scene_lights::setLights(light_indexing_info *info)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if ( info->index_start == current_light_index && info->num_lights == current_num_lights ) {
|
||||
// don't need to set new lights since the ones requested to be set are currently set
|
||||
return false;
|
||||
}
|
||||
|
||||
current_light_index = info->index_start;
|
||||
current_num_lights = info->num_lights;
|
||||
|
||||
gr_reset_lighting();
|
||||
|
||||
gr_set_lighting(true, true);
|
||||
|
||||
for ( i = 0; i < StaticLightIndices.size(); ++i) {
|
||||
int light_index = StaticLightIndices[i];
|
||||
|
||||
gr_set_light( &AllLights[light_index] );
|
||||
}
|
||||
|
||||
extern bool Deferred_lighting;
|
||||
if ( Deferred_lighting ) {
|
||||
opengl_change_active_lights(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
int index_start = info->index_start;
|
||||
int num_lights = info->num_lights;
|
||||
|
||||
// check if there are any lights to actually set
|
||||
if ( num_lights <= 0 || index_start < 0 ) {
|
||||
opengl_change_active_lights(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// we definitely shouldn't be exceeding the number of buffered lights
|
||||
Assert(index_start + num_lights <= BufferedLights.size());
|
||||
|
||||
for ( i = 0; i < num_lights; ++i ) {
|
||||
int buffered_light_index = index_start + i;
|
||||
int light_index = BufferedLights[buffered_light_index];
|
||||
|
||||
gr_set_light(&AllLights[light_index]);
|
||||
}
|
||||
|
||||
opengl_change_active_lights(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
+49
-11
@@ -25,24 +25,62 @@
|
||||
#define LT_DIRECTIONAL 0 // A light like a sun
|
||||
#define LT_POINT 1 // A point light, like an explosion
|
||||
#define LT_TUBE 2 // A tube light, like a fluorescent light
|
||||
#define LT_CONE 3 // A cone light, like a flood light
|
||||
|
||||
#define MAX_LIGHT_LEVELS 16
|
||||
|
||||
typedef struct light {
|
||||
int type; // What type of light this is
|
||||
vec3d vec; // location in world space of a point light or the direction of a directional light or the first point on the tube for a tube light
|
||||
vec3d vec2; // second point on a tube light
|
||||
vec3d local_vec; // rotated light vector
|
||||
vec3d local_vec2; // rotated 2nd light vector for a tube light
|
||||
float intensity; // How bright the light is.
|
||||
float rada, rada_squared; // How big of an area a point light affect. Is equal to l->intensity / MIN_LIGHT;
|
||||
float radb, radb_squared; // How big of an area a point light affect. Is equal to l->intensity / MIN_LIGHT;
|
||||
float r,g,b; // The color components of the light
|
||||
float spec_r,spec_g,spec_b; // The specular color components of the light
|
||||
vec3d vec2; // second point on a tube light or direction of a cone light
|
||||
vec3d local_vec; // rotated light vector
|
||||
vec3d local_vec2; // rotated 2nd light vector for a tube light
|
||||
float intensity; // How bright the light is.
|
||||
float rada, rada_squared; // How big of an area a point light affect. Is equal to l->intensity / MIN_LIGHT;
|
||||
float radb, radb_squared; // How big of an area a point light affect. Is equal to l->intensity / MIN_LIGHT;
|
||||
float r,g,b; // The color components of the light
|
||||
float spec_r,spec_g,spec_b; // The specular color components of the light
|
||||
int light_ignore_objnum; // Don't light this object. Used to optimize weapons casting light on parents.
|
||||
int affected_objnum; // for "unique lights". ie, lights which only affect one object (trust me, its useful)
|
||||
int affected_objnum; // for "unique lights". ie, lights which only affect one object (trust me, its useful)
|
||||
float cone_angle; // angle for cone lights
|
||||
float cone_inner_angle; // the inner angle for calculating falloff
|
||||
bool dual_cone; // should the cone be shining in both directions?
|
||||
int instance;
|
||||
} light;
|
||||
|
||||
extern SCP_vector<light*> Static_light;
|
||||
|
||||
struct light_indexing_info
|
||||
{
|
||||
int index_start;
|
||||
int num_lights;
|
||||
};
|
||||
|
||||
class scene_lights
|
||||
{
|
||||
SCP_vector<light> AllLights;
|
||||
|
||||
SCP_vector<int> StaticLightIndices;
|
||||
|
||||
SCP_vector<int> FilteredLights;
|
||||
|
||||
SCP_vector<int> BufferedLights;
|
||||
|
||||
int current_light_index;
|
||||
int current_num_lights;
|
||||
public:
|
||||
scene_lights()
|
||||
{
|
||||
resetLightState();
|
||||
}
|
||||
void addLight(light *light_ptr);
|
||||
void setLightFilter(int objnum, vec3d *pos, float rad);
|
||||
bool setLights(light_indexing_info *info);
|
||||
void resetLightState();
|
||||
int getNumStaticLights();
|
||||
light_indexing_info bufferLights();
|
||||
};
|
||||
|
||||
void light_reset();
|
||||
void light_set_ambient(float ambient_light);
|
||||
|
||||
@@ -52,6 +90,7 @@ void light_add_directional( vec3d *dir, float intensity, float r, float g, float
|
||||
void light_add_point( vec3d * pos, float r1, float r2, float intensity, float r, float g, float b, int light_ignore_objnum, float spec_r = 0.0f, float spec_g = 0.0f, float spec_b = 0.0f, bool specular = false );
|
||||
void light_add_point_unique( vec3d * pos, float r1, float r2, float intensity, float r, float g, float b, int affected_objnum, float spec_r = 0.0f, float spec_g = 0.0f, float spec_b = 0.0f, bool specular = false);
|
||||
void light_add_tube(vec3d *p0, vec3d *p1, float r1, float r2, float intensity, float r, float g, float b, int affected_objnum, float spec_r = 0.0f, float spec_g = 0.0f, float spec_b = 0.0f, bool specular = false);
|
||||
void light_add_cone( vec3d * pos, vec3d * dir, float angle, float inner_angle, bool dual_cone, float r1, float r2, float intensity, float r, float g, float b, int light_ignore_objnum, float spec_r = 0.0f, float spec_g = 0.0f, float spec_b = 0.0f, bool specular = false );
|
||||
void light_rotate_all();
|
||||
|
||||
// Reset the list of lights to point to all lights.
|
||||
@@ -85,6 +124,5 @@ int light_get_global_dir(vec3d *pos, int n);
|
||||
// Set to non-zero if we're in a shadow.
|
||||
void light_set_shadow( int state );
|
||||
|
||||
extern int cell_shaded_lightmap;
|
||||
|
||||
bool light_compare_by_type(const light &a, const light &b);
|
||||
#endif
|
||||
@@ -88,7 +88,11 @@ float fl_isqrt( float x )
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// sees if two floating point numbers are within the minimum tolerance
|
||||
inline bool fl_equal(float a, float b)
|
||||
{
|
||||
return fl_abs(a - b) <= FLT_EPSILON * MAX(1.0f, MAX(fl_abs(a), fl_abs(b)));
|
||||
}
|
||||
|
||||
// rounds off a floating point number to a multiple of some number
|
||||
extern float fl_roundoff(float x, int multiple);
|
||||
|
||||
@@ -33,6 +33,34 @@ matrix vmd_identity_matrix = IDENTITY_MATRIX;
|
||||
|
||||
#define UNINITIALIZED_VALUE -12345678.9f
|
||||
|
||||
bool vm_vec_equal(const vec4 &self, const vec4 &other)
|
||||
{
|
||||
return fl_equal(self.a1d[0], other.a1d[0]) && fl_equal(self.a1d[1], other.a1d[1]) && fl_equal(self.a1d[2], other.a1d[2]) && fl_equal(self.a1d[3], other.a1d[3]);
|
||||
}
|
||||
|
||||
bool vm_vec_equal(const vec3d &self, const vec3d &other)
|
||||
{
|
||||
return fl_equal(self.a1d[0], other.a1d[0]) && fl_equal(self.a1d[1], other.a1d[1]) && fl_equal(self.a1d[2], other.a1d[2]);
|
||||
}
|
||||
|
||||
bool vm_vec_equal(const vec2d &self, const vec2d &other)
|
||||
{
|
||||
return fl_equal(self.x, other.x) && fl_equal(self.y, other.y);
|
||||
}
|
||||
|
||||
bool vm_matrix_equal(const matrix &self, const matrix &other)
|
||||
{
|
||||
return vm_vec_equal(self.vec.fvec, other.vec.fvec) && vm_vec_equal(self.vec.uvec, other.vec.uvec) && vm_vec_equal(self.vec.rvec, other.vec.rvec);
|
||||
}
|
||||
|
||||
bool vm_matrix_equal(const matrix4 &self, const matrix4 &other)
|
||||
{
|
||||
return vm_vec_equal(self.vec.fvec, other.vec.fvec) &&
|
||||
vm_vec_equal(self.vec.rvec, other.vec.rvec) &&
|
||||
vm_vec_equal(self.vec.uvec, other.vec.uvec) &&
|
||||
vm_vec_equal(self.vec.pos, other.vec.pos);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// atan2_safe()
|
||||
//
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <float.h>
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "math/floating.h"
|
||||
|
||||
//#define _INLINE_VECMAT
|
||||
|
||||
@@ -217,6 +218,16 @@ void vm_vec_scale_add2(vec3d *dest,vec3d *src,float k);
|
||||
void vm_vec_scale2(vec3d *dest,float n,float d);
|
||||
#endif
|
||||
|
||||
bool vm_vec_equal(const vec2d &self, const vec2d &other);
|
||||
|
||||
bool vm_vec_equal(const vec3d &self, const vec3d &other);
|
||||
|
||||
bool vm_vec_equal(const vec4 &self, const vec4 &other);
|
||||
|
||||
bool vm_matrix_equal(const matrix &self, const matrix &other);
|
||||
|
||||
bool vm_matrix_equal(const matrix4 &self, const matrix4 &other);
|
||||
|
||||
// finds the projection of source vector along a unit vector
|
||||
// returns the magnitude of the component
|
||||
float vm_vec_projection_parallel (vec3d *component, vec3d *src, vec3d *unit_vector);
|
||||
|
||||
+34
-11
@@ -30,6 +30,7 @@
|
||||
#include "parse/parselo.h"
|
||||
#include "ship/ship.h"
|
||||
#include "weapon/weapon.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
|
||||
|
||||
|
||||
@@ -453,6 +454,8 @@ void tech_common_render()
|
||||
}
|
||||
}
|
||||
|
||||
void light_set_all_relevent();
|
||||
|
||||
void techroom_ships_render(float frametime)
|
||||
{
|
||||
// render all the common stuff
|
||||
@@ -466,9 +469,10 @@ void techroom_ships_render(float frametime)
|
||||
angles rot_angles, view_angles;
|
||||
int z, i, j;
|
||||
ship_info *sip = &Ship_info[Cur_entry_index];
|
||||
model_render_params render_info;
|
||||
|
||||
if (sip->uses_team_colors) {
|
||||
gr_set_team_color(sip->default_team_name, "none", 0, 0);
|
||||
render_info.set_team_color(sip->default_team_name, "none", 0, 0);
|
||||
}
|
||||
|
||||
// get correct revolution rate
|
||||
@@ -519,15 +523,13 @@ void techroom_ships_render(float frametime)
|
||||
g3_start_frame(1);
|
||||
g3_set_view_matrix(&sip->closeup_pos, &vmd_identity_matrix, sip->closeup_zoom * 1.3f);
|
||||
|
||||
if (!Cmdline_nohtl) {
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
}
|
||||
|
||||
|
||||
// lighting for techroom
|
||||
light_reset();
|
||||
vec3d light_dir = vmd_zero_vector;
|
||||
light_dir.xyz.y = 1.0f;
|
||||
light_dir.xyz.x = 0.0000001f;
|
||||
light_add_directional(&light_dir, 0.85f, 1.0f, 1.0f, 1.0f);
|
||||
light_rotate_all();
|
||||
// lighting for techroom
|
||||
@@ -535,15 +537,17 @@ void techroom_ships_render(float frametime)
|
||||
Glowpoint_use_depth_buffer = false;
|
||||
|
||||
model_clear_instance(Techroom_ship_modelnum);
|
||||
model_set_detail_level(0);
|
||||
render_info.set_detail_level_lock(0);
|
||||
|
||||
polymodel *pm = model_get(Techroom_ship_modelnum);
|
||||
|
||||
for (i = 0; i < sip->n_subsystems; i++) {
|
||||
model_subsystem *msp = &sip->subsystems[i];
|
||||
if (msp->type == SUBSYSTEM_TURRET) {
|
||||
|
||||
float p = 0.0f;
|
||||
float h = 0.0f;
|
||||
|
||||
|
||||
for (j = 0; j < msp->n_triggers; j++) {
|
||||
|
||||
// special case for turrets
|
||||
@@ -559,12 +563,32 @@ void techroom_ships_render(float frametime)
|
||||
}
|
||||
}
|
||||
|
||||
uint render_flags = MR_LOCK_DETAIL | MR_AUTOCENTER;
|
||||
if(Cmdline_shadow_quality)
|
||||
{
|
||||
gr_reset_clip();
|
||||
|
||||
shadows_start_render(&Eye_matrix, &Eye_position, Proj_fov, gr_screen.clip_aspect, -sip->closeup_pos.xyz.z + pm->rad, -sip->closeup_pos.xyz.z + pm->rad + 200.0f, -sip->closeup_pos.xyz.z + pm->rad + 2000.0f, -sip->closeup_pos.xyz.z + pm->rad + 10000.0f);
|
||||
render_info.set_flags(MR_NO_TEXTURING | MR_NO_LIGHTING | MR_AUTOCENTER);
|
||||
|
||||
model_render_immediate(&render_info, Techroom_ship_modelnum, &Techroom_ship_orient, &vmd_zero_vector);
|
||||
shadows_end_render();
|
||||
|
||||
gr_set_clip(Tech_ship_display_coords[gr_screen.res][SHIP_X_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_Y_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_W_COORD], Tech_ship_display_coords[gr_screen.res][SHIP_H_COORD]);
|
||||
}
|
||||
|
||||
if (!Cmdline_nohtl) {
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
}
|
||||
|
||||
uint render_flags = MR_AUTOCENTER;
|
||||
|
||||
if(sip->flags2 & SIF2_NO_LIGHTING)
|
||||
render_flags |= MR_NO_LIGHTING;
|
||||
render_flags |= MR_NO_LIGHTING;
|
||||
|
||||
model_render(Techroom_ship_modelnum, &Techroom_ship_orient, &vmd_zero_vector, render_flags);
|
||||
render_info.set_flags(render_flags);
|
||||
|
||||
model_render_immediate(&render_info, Techroom_ship_modelnum, &Techroom_ship_orient, &vmd_zero_vector);
|
||||
|
||||
Glowpoint_use_depth_buffer = true;
|
||||
|
||||
@@ -579,7 +603,6 @@ void techroom_ships_render(float frametime)
|
||||
g3_end_frame();
|
||||
|
||||
gr_reset_clip();
|
||||
gr_disable_team_color();
|
||||
}
|
||||
|
||||
// select previous entry in current list
|
||||
|
||||
@@ -3477,8 +3477,8 @@ void parse_common_object_data(p_object *objp)
|
||||
for (j=0; j < sip->n_subsystems; ++j)
|
||||
if (!subsystem_stricmp(sip->subsystems[j].subobj_name, Subsys_status[i].name))
|
||||
break;
|
||||
if (j == sip->n_subsystems)
|
||||
Warning(LOCATION, "Ship \"%s\", class \"%s\"\nUnknown subsystem \"%s\" found in mission!", objp->name, sip->name, Subsys_status[i].name);
|
||||
//if (j == sip->n_subsystems)
|
||||
//Warning(LOCATION, "Ship \"%s\", class \"%s\"\nUnknown subsystem \"%s\" found in mission!", objp->name, sip->name, Subsys_status[i].name);
|
||||
}
|
||||
|
||||
if (optional_string("$Damage:"))
|
||||
|
||||
@@ -1070,7 +1070,6 @@ void brief_render_closeup(int ship_class, float frametime)
|
||||
}
|
||||
|
||||
model_clear_instance( Closeup_icon->modelnum );
|
||||
model_set_detail_level(0);
|
||||
|
||||
int is_neb = The_mission.flags & MISSION_FLAG_FULLNEB;
|
||||
|
||||
@@ -1079,17 +1078,19 @@ void brief_render_closeup(int ship_class, float frametime)
|
||||
The_mission.flags &= ~MISSION_FLAG_FULLNEB;
|
||||
}
|
||||
|
||||
int model_render_flags_local;
|
||||
model_render_params render_info;
|
||||
render_info.set_detail_level_lock(0);
|
||||
|
||||
if ( Closeup_icon->type == ICON_JUMP_NODE) {
|
||||
model_set_outline_color(HUD_color_red, HUD_color_green, HUD_color_blue);
|
||||
model_render_flags_local = MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_POLYS | MR_SHOW_OUTLINE;
|
||||
render_info.set_outline_color(HUD_color_red, HUD_color_green, HUD_color_blue);
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_AUTOCENTER | MR_NO_POLYS | MR_SHOW_OUTLINE_HTL | MR_NO_TEXTURING);
|
||||
} else if (Cmdline_brief_lighting) {
|
||||
model_render_flags_local = MR_LOCK_DETAIL | MR_AUTOCENTER;
|
||||
render_info.set_flags(MR_AUTOCENTER);
|
||||
} else {
|
||||
model_render_flags_local = MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER;
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_AUTOCENTER);
|
||||
}
|
||||
|
||||
model_render( Closeup_icon->modelnum, &Closeup_orient, &Closeup_pos, model_render_flags_local );
|
||||
model_render_immediate( &render_info, Closeup_icon->modelnum, &Closeup_orient, &Closeup_pos );
|
||||
|
||||
if (is_neb) {
|
||||
The_mission.flags |= MISSION_FLAG_FULLNEB;
|
||||
|
||||
@@ -1583,7 +1583,8 @@ void draw_model_icon(int model_id, int flags, float closeup_zoom, int x, int y,
|
||||
}
|
||||
}
|
||||
|
||||
model_set_detail_level(0);
|
||||
model_render_params render_info;
|
||||
render_info.set_detail_level_lock(0);
|
||||
|
||||
if (!Cmdline_nohtl) {
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
@@ -1602,7 +1603,9 @@ void draw_model_icon(int model_id, int flags, float closeup_zoom, int x, int y,
|
||||
|
||||
Glowpoint_override = true;
|
||||
model_clear_instance(model_id);
|
||||
model_render(model_id, &object_orient, &vmd_zero_vector, flags, -1, -1);
|
||||
|
||||
render_info.set_flags(flags);
|
||||
model_render_immediate(&render_info, model_id, &object_orient, &vmd_zero_vector);
|
||||
Glowpoint_override = false;
|
||||
|
||||
if (!Cmdline_nohtl)
|
||||
@@ -1616,7 +1619,8 @@ void draw_model_icon(int model_id, int flags, float closeup_zoom, int x, int y,
|
||||
gr_reset_clip();
|
||||
}
|
||||
|
||||
void draw_model_rotating(int model_id, int x1, int y1, int x2, int y2, float *rotation_buffer, vec3d *closeup_pos, float closeup_zoom, float rev_rate, int flags, int resize_mode, int effect)
|
||||
void light_set_all_relevent();
|
||||
void draw_model_rotating(model_render_params *render_info, int model_id, int x1, int y1, int x2, int y2, float *rotation_buffer, vec3d *closeup_pos, float closeup_zoom, float rev_rate, int flags, int resize_mode, int effect)
|
||||
{
|
||||
//WMC - Can't draw a non-model
|
||||
if (model_id < 0)
|
||||
@@ -1693,7 +1697,7 @@ void draw_model_rotating(int model_id, int x1, int y1, int x2, int y2, float *ro
|
||||
float start_scale = MIN(time,0.5f)*2.5f;
|
||||
float offset = size*0.5f*MIN(MAX(time-3.0f,0.0f),0.6f)*1.66667f;
|
||||
if ( (time < 1.5f) && (time >= 0.5f) ) // Clip the grid if were in phase 1
|
||||
g3_start_user_clip_plane(&plane_point,&wire_normal);
|
||||
render_info->set_clip_plane(plane_point,wire_normal);
|
||||
|
||||
g3_start_instance_angles(&vmd_zero_vector,&view_angles);
|
||||
|
||||
@@ -1739,29 +1743,62 @@ void draw_model_rotating(int model_id, int x1, int y1, int x2, int y2, float *ro
|
||||
light_reset();
|
||||
vec3d light_dir = vmd_zero_vector;
|
||||
light_dir.xyz.y = 1.0f;
|
||||
light_dir.xyz.x = 0.0000001f;
|
||||
light_add_directional(&light_dir, 0.65f, 1.0f, 1.0f, 1.0f);
|
||||
light_rotate_all();
|
||||
// lighting for techroom
|
||||
|
||||
// render the ships
|
||||
model_clear_instance(model_id);
|
||||
model_set_detail_level(0);
|
||||
model_set_outline_color(80,49,160);
|
||||
opengl_shader_set_animated_effect(ANIMATED_SHADER_LOADOUTSELECT_FS2);
|
||||
opengl_shader_set_animated_timer(-clip);
|
||||
render_info->set_detail_level_lock(0);
|
||||
|
||||
gr_zbuffer_set(true);
|
||||
if(Cmdline_shadow_quality)
|
||||
{
|
||||
gr_end_view_matrix();
|
||||
gr_end_proj_matrix();
|
||||
|
||||
gr_reset_clip();
|
||||
|
||||
model_render_params shadow_render_info;
|
||||
|
||||
shadow_render_info.set_detail_level_lock(0);
|
||||
shadow_render_info.set_flags(flags | MR_NO_TEXTURING | MR_NO_LIGHTING);
|
||||
|
||||
if ( flags & MR_IS_MISSILE ) {
|
||||
shadows_start_render(&Eye_matrix, &Eye_position, Proj_fov, gr_screen.clip_aspect, -closeup_pos->xyz.z + pm->rad, -closeup_pos->xyz.z + pm->rad + 20.0f, -closeup_pos->xyz.z + pm->rad + 200.0f, -closeup_pos->xyz.z + pm->rad + 1000.0f);
|
||||
} else {
|
||||
shadows_start_render(&Eye_matrix, &Eye_position, Proj_fov, gr_screen.clip_aspect, -closeup_pos->xyz.z + pm->rad, -closeup_pos->xyz.z + pm->rad + 200.0f, -closeup_pos->xyz.z + pm->rad + 2000.0f, -closeup_pos->xyz.z + pm->rad + 10000.0f);
|
||||
}
|
||||
|
||||
model_render_immediate(&shadow_render_info, model_id, &model_orient, &vmd_zero_vector);
|
||||
shadows_end_render();
|
||||
|
||||
gr_set_clip(x1, y1, x2, y2, resize_mode);
|
||||
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
}
|
||||
gr_zbuffer_set(false);
|
||||
gr_set_color(80,49,160);
|
||||
render_info->set_outline_color(80, 49, 160);
|
||||
|
||||
render_info->set_animated_effect(ANIMATED_SHADER_LOADOUTSELECT_FS2, -clip);
|
||||
|
||||
if ( (time < 2.5f) && (time >= 0.5f) ) { // Phase 1 and 2 render the wireframe
|
||||
if (time >= 1.5f) // Just clip the wireframe after Phase 1
|
||||
g3_start_user_clip_plane(&plane_point,&wire_normal);
|
||||
render_info->set_clip_plane(plane_point,wire_normal);
|
||||
|
||||
model_render(model_id, &model_orient, &vmd_zero_vector, flags | MR_SHOW_OUTLINE_HTL | MR_NO_POLYS | MR_ANIMATED_SHADER);
|
||||
g3_stop_user_clip_plane();
|
||||
render_info->set_flags(flags | MR_SHOW_OUTLINE_HTL | MR_NO_POLYS | MR_NO_TEXTURING | MR_NO_LIGHTING);
|
||||
|
||||
model_render_immediate(render_info, model_id, &model_orient, &vmd_zero_vector);
|
||||
}
|
||||
|
||||
if (time >= 1.5f) { // Render the ship in Phase 2 onwards
|
||||
g3_start_user_clip_plane(&plane_point,&ship_normal);
|
||||
model_render(model_id, &model_orient, &vmd_zero_vector, flags | MR_ANIMATED_SHADER);
|
||||
g3_stop_user_clip_plane();
|
||||
render_info->set_clip_plane(plane_point,ship_normal);
|
||||
render_info->set_flags(flags);
|
||||
|
||||
model_render_immediate(render_info, model_id, &model_orient, &vmd_zero_vector);
|
||||
}
|
||||
|
||||
if (time < 2.5f) { // Render the scanline in Phase 1 and 2
|
||||
@@ -1805,21 +1842,18 @@ void draw_model_rotating(int model_id, int x1, int y1, int x2, int y2, float *ro
|
||||
rot_angles.h = *rotation_buffer;
|
||||
vm_rotate_matrix_by_angles(&model_orient, &rot_angles);
|
||||
|
||||
gr_set_clip(x1, y1, x2, y2, resize_mode);
|
||||
g3_start_frame(1);
|
||||
|
||||
polymodel *pm = model_get(model_id);
|
||||
|
||||
// render the wodel
|
||||
if ( (closeup_pos != NULL) && (vm_vec_mag(closeup_pos) > 0.0f) ) {
|
||||
g3_set_view_matrix(closeup_pos, &vmd_identity_matrix, closeup_zoom);
|
||||
} else {
|
||||
polymodel *pm = model_get(model_id);
|
||||
vec3d pos = { { { 0.0f, 0.0f, -(pm->rad * 1.5f) } } };
|
||||
g3_set_view_matrix(&pos, &vmd_identity_matrix, closeup_zoom);
|
||||
}
|
||||
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
|
||||
// lighting for techroom
|
||||
light_reset();
|
||||
vec3d light_dir = vmd_zero_vector;
|
||||
@@ -1829,17 +1863,42 @@ void draw_model_rotating(int model_id, int x1, int y1, int x2, int y2, float *ro
|
||||
// lighting for techroom
|
||||
|
||||
model_clear_instance(model_id);
|
||||
model_set_detail_level(0);
|
||||
|
||||
render_info->set_detail_level_lock(0);
|
||||
|
||||
if(Cmdline_shadow_quality)
|
||||
{
|
||||
if ( flags & MR_IS_MISSILE ) {
|
||||
shadows_start_render(&Eye_matrix, &Eye_position, Proj_fov, gr_screen.clip_aspect, -closeup_pos->xyz.z + pm->rad, -closeup_pos->xyz.z + pm->rad + 20.0f, -closeup_pos->xyz.z + pm->rad + 200.0f, -closeup_pos->xyz.z + pm->rad + 1000.0f);
|
||||
} else {
|
||||
shadows_start_render(&Eye_matrix, &Eye_position, Proj_fov, gr_screen.clip_aspect, -closeup_pos->xyz.z + pm->rad, -closeup_pos->xyz.z + pm->rad + 200.0f, -closeup_pos->xyz.z + pm->rad + 2000.0f, -closeup_pos->xyz.z + pm->rad + 10000.0f);
|
||||
}
|
||||
|
||||
model_render_params shadow_render_info;
|
||||
|
||||
shadow_render_info.set_flags(flags | MR_NO_TEXTURING | MR_NO_LIGHTING);
|
||||
shadow_render_info.set_detail_level_lock(0);
|
||||
|
||||
model_render_immediate(&shadow_render_info, model_id, &model_orient, &vmd_zero_vector);
|
||||
shadows_end_render();
|
||||
}
|
||||
|
||||
gr_set_clip(x1, y1, x2, y2, resize_mode);
|
||||
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
|
||||
gr_set_color(0,128,0);
|
||||
|
||||
if (effect == 1) { // FS1 effect
|
||||
opengl_shader_set_animated_effect(ANIMATED_SHADER_LOADOUTSELECT_FS1);
|
||||
opengl_shader_set_animated_timer(MIN(time*0.5f,2.0f));
|
||||
model_render(model_id, &model_orient, &vmd_zero_vector, flags | MR_ANIMATED_SHADER);
|
||||
render_info->set_animated_effect(ANIMATED_SHADER_LOADOUTSELECT_FS1, MIN(time*0.5f,2.0f));
|
||||
render_info->set_flags(flags);
|
||||
} else {
|
||||
model_render(model_id, &model_orient, &vmd_zero_vector, flags);
|
||||
render_info->set_flags(flags);
|
||||
}
|
||||
|
||||
model_render_immediate(render_info, model_id, &model_orient, &vmd_zero_vector);
|
||||
|
||||
batch_render_all();
|
||||
|
||||
gr_end_view_matrix();
|
||||
|
||||
@@ -204,7 +204,7 @@ int restore_wss_data(ubyte *block);
|
||||
|
||||
class ship_info;
|
||||
void draw_model_icon(int model_id, int flags, float closeup_zoom, int x1, int x2, int y1, int y2, ship_info* sip=NULL, int resize_mode=GR_RESIZE_FULL);
|
||||
void draw_model_rotating(int model_id, int x1, int y1, int x2, int y2, float *rotation_buffer, vec3d *closeup_pos=NULL, float closeup_zoom = .65f, float rev_rate = REVOLUTION_RATE, int flags = MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING, int resize_mode=GR_RESIZE_FULL, int effect = 2);
|
||||
void draw_model_rotating(model_render_params *render_info, int model_id, int x1, int y1, int x2, int y2, float *rotation_buffer, vec3d *closeup_pos=NULL, float closeup_zoom = .65f, float rev_rate = REVOLUTION_RATE, int flags = MR_AUTOCENTER | MR_NO_FOGGING, int resize_mode=GR_RESIZE_FULL, int effect = 2);
|
||||
|
||||
void common_set_team_pointers(int team);
|
||||
void common_reset_team_pointers();
|
||||
|
||||
@@ -1474,11 +1474,15 @@ void ship_select_do(float frametime)
|
||||
rev_rate *= 3.0f;
|
||||
}
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
if (sip->uses_team_colors) {
|
||||
gr_set_team_color(sip->default_team_name, "none", 0, 0);
|
||||
render_info.set_team_color(sip->default_team_name, "none", 0, 0);
|
||||
}
|
||||
|
||||
draw_model_rotating(ShipSelectModelNum,
|
||||
draw_model_rotating(
|
||||
&render_info,
|
||||
ShipSelectModelNum,
|
||||
Ship_anim_coords[gr_screen.res][0],
|
||||
Ship_anim_coords[gr_screen.res][1],
|
||||
Tech_ship_display_coords[gr_screen.res][2],
|
||||
@@ -1487,11 +1491,9 @@ void ship_select_do(float frametime)
|
||||
&sip->closeup_pos,
|
||||
sip->closeup_zoom * 1.3f,
|
||||
rev_rate,
|
||||
MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING,
|
||||
MR_AUTOCENTER | MR_NO_FOGGING,
|
||||
GR_RESIZE_MENU,
|
||||
sip->selection_effect);
|
||||
|
||||
gr_disable_team_color();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1528,7 +1530,7 @@ void ship_select_do(float frametime)
|
||||
|
||||
if(Ss_icons[Carried_ss_icon.ship_class].model_index != -1)
|
||||
{
|
||||
draw_model_icon(Ss_icons[Carried_ss_icon.ship_class].model_index, MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_LIGHTING, sip->closeup_zoom / 1.25f, sx, sy, w, h, sip, GR_RESIZE_MENU);
|
||||
draw_model_icon(Ss_icons[Carried_ss_icon.ship_class].model_index, MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_LIGHTING, sip->closeup_zoom / 1.25f, sx, sy, w, h, sip, GR_RESIZE_MENU);
|
||||
}
|
||||
draw_brackets_square(sx, sy, sx + w, sy + h, GR_RESIZE_MENU);
|
||||
//gr_shade(mouse_x + Ss_delta_x, mouse_y + Ss_delta_y, 32, 28, GR_RESIZE_MENU);
|
||||
@@ -1714,7 +1716,7 @@ void draw_ship_icon_with_number(int screen_offset, int ship_class)
|
||||
//gr_set_shader(shader_to_use);
|
||||
if(ss_icon->model_index != -1)
|
||||
{
|
||||
draw_model_icon(ss_icon->model_index, MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_LIGHTING, sip->closeup_zoom / 1.25f, Ship_list_coords[gr_screen.res][screen_offset][0],Ship_list_coords[gr_screen.res][screen_offset][1], 32, 28, sip, GR_RESIZE_MENU);
|
||||
draw_model_icon(ss_icon->model_index, MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_LIGHTING, sip->closeup_zoom / 1.25f, Ship_list_coords[gr_screen.res][screen_offset][0],Ship_list_coords[gr_screen.res][screen_offset][1], 32, 28, sip, GR_RESIZE_MENU);
|
||||
}
|
||||
draw_brackets_square(Ship_list_coords[gr_screen.res][screen_offset][0], Ship_list_coords[gr_screen.res][screen_offset][1], Ship_list_coords[gr_screen.res][screen_offset][0] + 32, Ship_list_coords[gr_screen.res][screen_offset][1] + 28, GR_RESIZE_MENU);
|
||||
//gr_shade(Ship_list_coords[gr_screen.res][screen_offset][0],Ship_list_coords[gr_screen.res][screen_offset][1], 32, 28, GR_RESIZE_MENU);
|
||||
@@ -2220,7 +2222,7 @@ void draw_wing_block(int wb_num, int hot_slot, int selected_slot, int class_sele
|
||||
ship_info *sip = &Ship_info[Wss_slots[slot_index].ship_class];
|
||||
gr_set_color_fast(color_to_draw);
|
||||
//gr_set_shader(shader_to_use);
|
||||
draw_model_icon(icon->model_index, MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_LIGHTING, sip->closeup_zoom / 1.25f, Wing_icon_coords[gr_screen.res][slot_index][0], Wing_icon_coords[gr_screen.res][slot_index][1], 32, 28, sip, GR_RESIZE_MENU);
|
||||
draw_model_icon(icon->model_index, MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_LIGHTING, sip->closeup_zoom / 1.25f, Wing_icon_coords[gr_screen.res][slot_index][0], Wing_icon_coords[gr_screen.res][slot_index][1], 32, 28, sip, GR_RESIZE_MENU);
|
||||
draw_brackets_square(Wing_icon_coords[gr_screen.res][slot_index][0], Wing_icon_coords[gr_screen.res][slot_index][1], Wing_icon_coords[gr_screen.res][slot_index][0] + 32, Wing_icon_coords[gr_screen.res][slot_index][1] + 28, GR_RESIZE_MENU);
|
||||
//gr_shade(Wing_icon_coords[gr_screen.res][slot_index][0], Wing_icon_coords[gr_screen.res][slot_index][1], 32, 28, GR_RESIZE_MENU);
|
||||
}
|
||||
@@ -2301,7 +2303,7 @@ void ss_blit_ship_icon(int x,int y,int ship_class,int bmap_num)
|
||||
{
|
||||
gr_set_color_fast(&Icon_colors[bmap_num]);
|
||||
//gr_set_shader(&Icon_shaders[bmap_num]);
|
||||
draw_model_icon(icon->model_index, MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_LIGHTING, sip->closeup_zoom / 1.25f, x, y, 32, 28, sip, GR_RESIZE_MENU);
|
||||
draw_model_icon(icon->model_index, MR_AUTOCENTER | MR_NO_FOGGING | MR_NO_LIGHTING, sip->closeup_zoom / 1.25f, x, y, 32, 28, sip, GR_RESIZE_MENU);
|
||||
draw_brackets_square(x, y, x + 32, y + 28, GR_RESIZE_MENU);
|
||||
//gr_shade(x, y, 32, 28, GR_RESIZE_MENU);
|
||||
}
|
||||
|
||||
@@ -871,15 +871,13 @@ void wl_render_overhead_view(float frametime)
|
||||
vm_rotate_matrix_by_angles(&object_orient, &rot_angles);
|
||||
}
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
gr_set_clip(Wl_overhead_coords[gr_screen.res][0], Wl_overhead_coords[gr_screen.res][1], gr_screen.res == 0 ? 291 : 467, gr_screen.res == 0 ? 226 : 362, GR_RESIZE_MENU);
|
||||
g3_start_frame(1);
|
||||
g3_set_view_matrix( &sip->closeup_pos, &Eye_matrix, zoom);
|
||||
model_set_detail_level(0);
|
||||
|
||||
if (!Cmdline_nohtl) {
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
}
|
||||
render_info.set_detail_level_lock(0);
|
||||
|
||||
|
||||
light_reset();
|
||||
vec3d light_dir = vmd_zero_vector;
|
||||
@@ -892,7 +890,29 @@ void wl_render_overhead_view(float frametime)
|
||||
Glowpoint_use_depth_buffer = false;
|
||||
|
||||
model_clear_instance(wl_ship->model_num);
|
||||
model_render(wl_ship->model_num, &object_orient, &vmd_zero_vector, MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING, -1, -1);
|
||||
polymodel *pm = model_get(wl_ship->model_num);
|
||||
|
||||
if(Cmdline_shadow_quality)
|
||||
{
|
||||
gr_reset_clip();
|
||||
shadows_start_render(&Eye_matrix, &Eye_position, Proj_fov, gr_screen.clip_aspect, -sip->closeup_pos.xyz.z + pm->rad,
|
||||
-sip->closeup_pos.xyz.z + pm->rad + 200.0f, -sip->closeup_pos.xyz.z + pm->rad + 2000.0f, -sip->closeup_pos.xyz.z + pm->rad + 10000.0f);
|
||||
|
||||
render_info.set_flags(MR_NO_TEXTURING | MR_NO_LIGHTING | MR_AUTOCENTER);
|
||||
|
||||
model_render_immediate(&render_info, wl_ship->model_num, &object_orient, &vmd_zero_vector);
|
||||
shadows_end_render();
|
||||
gr_set_clip(Wl_overhead_coords[gr_screen.res][0], Wl_overhead_coords[gr_screen.res][1], gr_screen.res == 0 ? 291 : 467, gr_screen.res == 0 ? 226 : 362, GR_RESIZE_MENU);
|
||||
}
|
||||
|
||||
if (!Cmdline_nohtl) {
|
||||
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, Min_draw_distance, Max_draw_distance);
|
||||
gr_set_view_matrix(&Eye_position, &Eye_matrix);
|
||||
}
|
||||
|
||||
render_info.set_flags(MR_AUTOCENTER | MR_NO_FOGGING);
|
||||
|
||||
model_render_immediate(&render_info, wl_ship->model_num, &object_orient, &vmd_zero_vector);
|
||||
|
||||
Glowpoint_use_depth_buffer = true;
|
||||
|
||||
@@ -904,7 +924,6 @@ void wl_render_overhead_view(float frametime)
|
||||
vec3d subobj_pos;
|
||||
int x, y;
|
||||
int xc, yc;
|
||||
polymodel *pm = model_get(wl_ship->model_num);
|
||||
int num_found = 2;
|
||||
|
||||
//Render selected primary lines
|
||||
@@ -2665,7 +2684,9 @@ void weapon_select_do(float frametime)
|
||||
static float WeapSelectScreenWeapRot = 0.0f;
|
||||
wl_icon_info *sel_icon = &Wl_icons[Selected_wl_class];
|
||||
weapon_info *wip = &Weapon_info[Selected_wl_class];
|
||||
draw_model_rotating(sel_icon->model_index,
|
||||
model_render_params render_info;
|
||||
draw_model_rotating(&render_info,
|
||||
sel_icon->model_index,
|
||||
weapon_ani_coords[0],
|
||||
weapon_ani_coords[1],
|
||||
gr_screen.res == 0 ? 202 : 332,
|
||||
@@ -2674,7 +2695,7 @@ void weapon_select_do(float frametime)
|
||||
&Weapon_info->closeup_pos,
|
||||
Weapon_info->closeup_zoom * 0.65f,
|
||||
REVOLUTION_RATE,
|
||||
MR_IS_MISSILE | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING,
|
||||
MR_IS_MISSILE | MR_AUTOCENTER | MR_NO_FOGGING,
|
||||
GR_RESIZE_MENU,
|
||||
wip->selection_effect);
|
||||
}
|
||||
@@ -2730,7 +2751,7 @@ void weapon_select_do(float frametime)
|
||||
if(icon->model_index != -1)
|
||||
{
|
||||
//Draw the model
|
||||
draw_model_icon(icon->model_index, MR_LOCK_DETAIL | MR_NO_FOGGING | MR_NO_LIGHTING, Weapon_info->closeup_zoom / 2.5f, sx, sy, w, h, NULL, GR_RESIZE_MENU);
|
||||
draw_model_icon(icon->model_index, MR_NO_FOGGING | MR_NO_LIGHTING, Weapon_info->closeup_zoom / 2.5f, sx, sy, w, h, NULL, GR_RESIZE_MENU);
|
||||
}
|
||||
else if(icon->laser_bmap != -1)
|
||||
{
|
||||
@@ -2973,7 +2994,7 @@ void wl_render_icon(int index, int x, int y, int num, int draw_num_flag, int hot
|
||||
if(icon->model_index != -1)
|
||||
{
|
||||
//Draw the model
|
||||
draw_model_icon(icon->model_index, MR_LOCK_DETAIL | MR_NO_FOGGING | MR_NO_LIGHTING, Weapon_info[index].closeup_zoom * 0.4f, x, y, 56, 24, NULL, GR_RESIZE_MENU);
|
||||
draw_model_icon(icon->model_index, MR_NO_FOGGING | MR_NO_LIGHTING, Weapon_info[index].closeup_zoom * 0.4f, x, y, 56, 24, NULL, GR_RESIZE_MENU);
|
||||
}
|
||||
else if(icon->laser_bmap != -1)
|
||||
{
|
||||
|
||||
+150
-39
@@ -18,6 +18,7 @@
|
||||
#include "object/object.h"
|
||||
|
||||
class object;
|
||||
class model_render_params;
|
||||
|
||||
extern flag_def_list model_render_flags[];
|
||||
extern int model_render_flags_size;
|
||||
@@ -89,6 +90,7 @@ typedef struct submodel_instance {
|
||||
matrix mc_orient;
|
||||
bool collision_checked;
|
||||
bool blown_off;
|
||||
bool moved_this_frame;
|
||||
} submodel_instance;
|
||||
|
||||
// Data specific to a particular instance of a model.
|
||||
@@ -96,6 +98,7 @@ typedef struct polymodel_instance {
|
||||
int model_num; // global model num index, same as polymodel->id
|
||||
int root_submodel_num; // unused?
|
||||
submodel_instance *submodel; // array of submodel instances; mirrors the polymodel->submodel array
|
||||
submodel_instance *submodel_render; // array of submodel instances for the rendering system; mirrors the polymodel->submodel array
|
||||
} polymodel_instance;
|
||||
|
||||
#define MAX_MODEL_SUBSYSTEMS 200 // used in ships.cpp (only place?) for local stack variable DTP; bumped to 200
|
||||
@@ -307,7 +310,8 @@ public:
|
||||
: movement_type(-1), movement_axis(0), can_move(false), bsp_data_size(0), bsp_data(NULL), collision_tree_index(-1),
|
||||
rad(0.0f), blown_off(0), my_replacement(-1), i_replace(-1), is_live_debris(0), num_live_debris(0), sii(NULL),
|
||||
is_thruster(0), is_damaged(0), parent(-1), num_children(0), first_child(-1), next_sibling(-1), num_details(0),
|
||||
num_arcs(0), render_sphere_radius(0.0f), use_render_box(0), use_render_box_offset(false), use_render_sphere(0), use_render_sphere_offset(false), gun_rotation(false), no_collisions(false),
|
||||
num_arcs(0), outline_buffer(NULL), n_verts_outline(0), render_sphere_radius(0.0f), use_render_box(0), use_render_box_offset(false),
|
||||
use_render_sphere(0), use_render_sphere_offset(false), gun_rotation(false), no_collisions(false),
|
||||
nocollide_this_only(false), collide_invisible(false), force_turret_normal(false), attach_thrusters(false), dumb_turn_rate(0.0f),
|
||||
look_at_num(-1)
|
||||
{
|
||||
@@ -378,6 +382,10 @@ public:
|
||||
|
||||
// buffers used by HT&L
|
||||
vertex_buffer buffer;
|
||||
vertex_buffer trans_buffer;
|
||||
|
||||
vertex *outline_buffer;
|
||||
uint n_verts_outline;
|
||||
|
||||
vec3d render_box_min;
|
||||
vec3d render_box_max;
|
||||
@@ -454,6 +462,11 @@ typedef struct thruster_bank {
|
||||
int submodel_num; // what submodel number this bank is on; index to polymodel->submodel/polymodel_instance->submodel
|
||||
} thruster_bank;
|
||||
|
||||
#define PULSE_SIN 1
|
||||
#define PULSE_COS 2
|
||||
#define PULSE_TRI 3
|
||||
#define PULSE_SHIFTTRI 4
|
||||
|
||||
typedef struct glow_point_bank { // glow bank structure -Bobboau
|
||||
int type;
|
||||
int glow_timestamp;
|
||||
@@ -469,6 +482,43 @@ typedef struct glow_point_bank { // glow bank structure -Bobboau
|
||||
int glow_neb_bitmap;
|
||||
} glow_point_bank;
|
||||
|
||||
typedef struct glow_point_bank_override {
|
||||
char name[33];
|
||||
int type;
|
||||
int on_time;
|
||||
int off_time;
|
||||
int disp_time;
|
||||
int glow_bitmap;
|
||||
int glow_neb_bitmap;
|
||||
bool is_on;
|
||||
|
||||
bool type_override;
|
||||
bool on_time_override;
|
||||
bool off_time_override;
|
||||
bool disp_time_override;
|
||||
bool glow_bitmap_override;
|
||||
|
||||
ubyte pulse_type;
|
||||
int pulse_period;
|
||||
float pulse_amplitude;
|
||||
float pulse_bias;
|
||||
float pulse_exponent;
|
||||
bool is_lightsource;
|
||||
float radius_multi;
|
||||
vec3d light_color;
|
||||
vec3d light_mix_color;
|
||||
bool lightcone;
|
||||
float cone_angle;
|
||||
float cone_inner_angle;
|
||||
vec3d cone_direction;
|
||||
bool dualcone;
|
||||
bool rotating;
|
||||
vec3d rotation_axis;
|
||||
float rotation_speed;
|
||||
|
||||
bool pulse_period_override;
|
||||
} glow_point_bank_override;
|
||||
|
||||
// defines for docking bay things. The types are essentially flags since docking bays can probably
|
||||
// be used for multiple things in some cases (i.e. rearming and general docking)
|
||||
//WMC - IMPORTANT, update Dock_type_names array if you add a new one of these
|
||||
@@ -579,6 +629,8 @@ typedef struct insignia {
|
||||
|
||||
#define PM_FLAG_ALLOW_TILING (1<<0) // Allow texture tiling
|
||||
#define PM_FLAG_AUTOCEN (1<<1) // contains autocentering info
|
||||
#define PM_FLAG_TRANS_BUFFER (1<<2) // render transparency buffer
|
||||
#define PM_FLAG_BATCHED (1<<3) // this model can be batch rendered
|
||||
|
||||
// Goober5000
|
||||
class texture_info
|
||||
@@ -770,6 +822,8 @@ public:
|
||||
float gun_submodel_rotation;
|
||||
|
||||
int vertex_buffer_id; // HTL vertex buffer id
|
||||
|
||||
vertex_buffer detail_buffers[MAX_MODEL_DETAIL_LEVELS];
|
||||
};
|
||||
|
||||
// Call once to initialize the model system
|
||||
@@ -812,12 +866,12 @@ void model_set_detail_level(int n);
|
||||
// Flags you can pass to model_render
|
||||
#define MR_NORMAL (0) // Draw a normal object
|
||||
#define MR_SHOW_OUTLINE (1<<0) // Draw the object in outline mode. Color specified by model_set_outline_color
|
||||
#define MR_SHOW_PIVOTS (1<<1) // Show the pivot points
|
||||
#define MR_SHOW_PATHS (1<<2) // Show the paths associated with a model
|
||||
#define MR_SHOW_RADIUS (1<<3) // Show the radius around the object
|
||||
#define MR_SHOW_SHIELDS (1<<4) // Show the shield mesh
|
||||
#define MR_SKYBOX (1<<1) // Draw as a skybox
|
||||
#define MR_DESATURATED (1<<2) // Draw model in monochrome using outline color
|
||||
#define MR_EMPTY_SLOT0 (1<<3) // Show the radius around the object
|
||||
#define MR_EMPTY_SLOT1 (1<<4) // Show the shield mesh
|
||||
#define MR_SHOW_THRUSTERS (1<<5) // Show the engine thrusters. See model_set_thrust for how long it draws.
|
||||
#define MR_LOCK_DETAIL (1<<6) // Only draw the detail level defined in model_set_detail_level
|
||||
#define MR_EMPTY_SLOT2 (1<<6) // Only draw the detail level defined in model_set_detail_level
|
||||
#define MR_NO_POLYS (1<<7) // Don't draw the polygons.
|
||||
#define MR_NO_LIGHTING (1<<8) // Don't perform any lighting on the model.
|
||||
#define MR_NO_TEXTURING (1<<9) // Draw textures as flat-shaded polygons.
|
||||
@@ -828,12 +882,12 @@ void model_set_detail_level(int n);
|
||||
#define MR_SHOW_OUTLINE_PRESET (1<<14) // Draw the object in outline mode. Color assumed to be set already.
|
||||
#define MR_SHOW_INVISIBLE_FACES (1<<15) // Show invisible faces as green...
|
||||
#define MR_AUTOCENTER (1<<16) // Always use the center of the hull bounding box as the center, instead of the pivot point
|
||||
#define MR_BAY_PATHS (1<<17) // draw bay paths
|
||||
#define MR_EMPTY_SLOT3 (1<<17) // draw bay paths
|
||||
#define MR_ALL_XPARENT (1<<18) // render it fully transparent
|
||||
#define MR_NO_ZBUFFER (1<<19) // switch z-buffering off completely
|
||||
#define MR_NO_CULL (1<<20) // don't cull backfacing poly's
|
||||
#define MR_FORCE_TEXTURE (1<<21) // force a given texture to always be used
|
||||
#define MR_FORCE_LOWER_DETAIL (1<<22) // force the model to draw 1 LOD lower, if possible
|
||||
#define MR_EMPTY_SLOT4 (1<<21) // force a given texture to always be used
|
||||
#define MR_NO_BATCH (1<<22) // don't use submodel batching when rendering
|
||||
#define MR_EDGE_ALPHA (1<<23) // makes norms that are faceing away from you render more transparent -Bobboau
|
||||
#define MR_CENTER_ALPHA (1<<24) // oposite of above -Bobboau
|
||||
#define MR_NO_FOGGING (1<<25) // Don't fog - taylor
|
||||
@@ -841,16 +895,61 @@ void model_set_detail_level(int n);
|
||||
#define MR_NO_GLOWMAPS (1<<27) // disable rendering of glowmaps - taylor
|
||||
#define MR_FULL_DETAIL (1<<28) // render all valid objects, particularly ones that are otherwise in/out of render boxes - taylor
|
||||
#define MR_FORCE_CLAMP (1<<29) // force clamp - Hery
|
||||
#define MR_ANIMATED_SHADER (1<<30) // Use a animated Shader - Valathil
|
||||
#define MR_EMPTY_SLOT5 (1<<30) // Use a animated Shader - Valathil
|
||||
#define MR_ATTACHED_MODEL (1<<31) // Used for attached weapon model lodding
|
||||
|
||||
#define MR_DEPRECATED_NORMAL (0) // Draw a normal object
|
||||
#define MR_DEPRECATED_SHOW_OUTLINE (1<<0) // Draw the object in outline mode. Color specified by model_set_outline_color
|
||||
#define MR_DEPRECATED_SHOW_PIVOTS (1<<1) // Show the pivot points
|
||||
#define MR_DEPRECATED_SHOW_PATHS (1<<2) // Show the paths associated with a model
|
||||
#define MR_DEPRECATED_SHOW_RADIUS (1<<3) // Show the radius around the object
|
||||
#define MR_DEPRECATED_SHOW_SHIELDS (1<<4) // Show the shield mesh
|
||||
#define MR_DEPRECATED_SHOW_THRUSTERS (1<<5) // Show the engine thrusters. See model_set_thrust for how long it draws.
|
||||
#define MR_DEPRECATED_LOCK_DETAIL (1<<6) // Only draw the detail level defined in model_set_detail_level
|
||||
#define MR_DEPRECATED_NO_POLYS (1<<7) // Don't draw the polygons.
|
||||
#define MR_DEPRECATED_NO_LIGHTING (1<<8) // Don't perform any lighting on the model.
|
||||
#define MR_DEPRECATED_NO_TEXTURING (1<<9) // Draw textures as flat-shaded polygons.
|
||||
#define MR_DEPRECATED_NO_CORRECT (1<<10) // Don't to correct texture mapping
|
||||
#define MR_DEPRECATED_NO_SMOOTHING (1<<11) // Don't perform smoothing on vertices.
|
||||
#define MR_DEPRECATED_IS_ASTEROID (1<<12) // When set, treat this as an asteroid.
|
||||
#define MR_DEPRECATED_IS_MISSILE (1<<13) // When set, treat this as a missilie. No lighting, small thrusters.
|
||||
#define MR_DEPRECATED_SHOW_OUTLINE_PRESET (1<<14) // Draw the object in outline mode. Color assumed to be set already.
|
||||
#define MR_DEPRECATED_SHOW_INVISIBLE_FACES (1<<15) // Show invisible faces as green...
|
||||
#define MR_DEPRECATED_AUTOCENTER (1<<16) // Always use the center of the hull bounding box as the center, instead of the pivot point
|
||||
#define MR_DEPRECATED_BAY_PATHS (1<<17) // draw bay paths
|
||||
#define MR_DEPRECATED_ALL_XPARENT (1<<18) // render it fully transparent
|
||||
#define MR_DEPRECATED_NO_ZBUFFER (1<<19) // switch z-buffering off completely
|
||||
#define MR_DEPRECATED_NO_CULL (1<<20) // don't cull backfacing poly's
|
||||
#define MR_DEPRECATED_FORCE_TEXTURE (1<<21) // force a given texture to always be used
|
||||
#define MR_DEPRECATED_FORCE_LOWER_DETAIL (1<<22) // force the model to draw 1 LOD lower, if possible
|
||||
#define MR_DEPRECATED_EDGE_ALPHA (1<<23) // makes norms that are faceing away from you render more transparent -Bobboau
|
||||
#define MR_DEPRECATED_CENTER_ALPHA (1<<24) // oposite of above -Bobboau
|
||||
#define MR_DEPRECATED_NO_FOGGING (1<<25) // Don't fog - taylor
|
||||
#define MR_DEPRECATED_SHOW_OUTLINE_HTL (1<<26) // Show outlines (wireframe view) using HTL method
|
||||
#define MR_DEPRECATED_NO_GLOWMAPS (1<<27) // disable rendering of glowmaps - taylor
|
||||
#define MR_DEPRECATED_FULL_DETAIL (1<<28) // render all valid objects, particularly ones that are otherwise in/out of render boxes - taylor
|
||||
#define MR_DEPRECATED_FORCE_CLAMP (1<<29) // force clamp - Hery
|
||||
#define MR_DEPRECATED_ANIMATED_SHADER (1<<30) // Use a animated Shader - Valathil
|
||||
#define MR_DEPRECATED_ATTACHED_MODEL (1<<31) // Used for attached weapon model lodding
|
||||
|
||||
#define MR_DEBUG_PIVOTS (1<<0) // Show the pivot points
|
||||
#define MR_DEBUG_PATHS (1<<1) // Show the paths associated with a model
|
||||
#define MR_DEBUG_RADIUS (1<<2) // Show the radius around the object
|
||||
#define MR_DEBUG_SHIELDS (1<<3) // Show the shield mesh
|
||||
#define MR_DEBUG_BAY_PATHS (1<<4) // draw bay paths
|
||||
|
||||
//Defines for the render parameter of model_render, model_really_render and model_render_buffers
|
||||
#define MODEL_RENDER_OPAQUE 1
|
||||
#define MODEL_RENDER_TRANS 2
|
||||
#define MODEL_RENDER_ALL 3
|
||||
|
||||
// Renders a model and all it's submodels.
|
||||
// See MR_? defines for values for flags
|
||||
void model_render(int model_num, matrix *orient, vec3d * pos, uint flags = MR_NORMAL, int objnum = -1, int lighting_skip = -1, int *replacement_textures = NULL, const bool is_skybox = false);
|
||||
void model_render_DEPRECATED(int model_num, matrix *orient, vec3d * pos, uint flags = MR_DEPRECATED_NORMAL, int objnum = -1, int lighting_skip = -1, int *replacement_textures = NULL, int render = MODEL_RENDER_ALL, const bool is_skybox = false);
|
||||
|
||||
// Renders just one particular submodel on a model.
|
||||
// See MR_? defines for values for flags
|
||||
void submodel_render(int model_num,int submodel_num, matrix *orient, vec3d * pos, uint flags = MR_NORMAL, int objnum = -1, int *replacement_textures = NULL);
|
||||
void submodel_render_DEPRECATED(int model_num,int submodel_num, matrix *orient, vec3d * pos, uint flags = MR_DEPRECATED_NORMAL, int objnum = -1, int *replacement_textures = NULL, int render = MODEL_RENDER_ALL);
|
||||
|
||||
// Returns the radius of a model
|
||||
float model_get_radius(int modelnum);
|
||||
@@ -938,6 +1037,9 @@ extern void find_submodel_instance_world_point(vec3d *outpnt, object *ship_obj,
|
||||
// Given a polygon model index, find a list of rotating submodels to be used for collision
|
||||
void model_get_rotating_submodel_list(SCP_vector<int> *submodel_vector, object *objp);
|
||||
|
||||
// Given a polygon model index, get a list of a model tree starting from that index
|
||||
void model_get_submodel_tree_list(SCP_vector<int> &submodel_vector, polymodel* pm, int mn);
|
||||
|
||||
// For a rotating submodel, find a point on the axis
|
||||
void model_init_submodel_axis_pt(submodel_instance_info *sii, int model_num, int submodel_num);
|
||||
|
||||
@@ -1119,7 +1221,7 @@ bsp_collision_tree *model_get_bsp_collision_tree(int tree_index);
|
||||
void model_remove_bsp_collision_tree(int tree_index);
|
||||
int model_create_bsp_collision_tree();
|
||||
|
||||
void model_collide_preprocess(matrix *orient, int model_instance_num);
|
||||
void model_collide_preprocess(matrix *orient, int model_instance_num, int detail = 0);
|
||||
|
||||
// Sets the submodel instance data in a submodel
|
||||
// If show_damaged is true it shows only damaged submodels.
|
||||
@@ -1181,7 +1283,7 @@ typedef struct mst_info {
|
||||
|
||||
bool use_ab;
|
||||
float glow_noise;
|
||||
const vec3d *rotvel;
|
||||
vec3d rotvel;
|
||||
vec3d length;
|
||||
|
||||
float glow_rad_factor;
|
||||
@@ -1193,36 +1295,12 @@ typedef struct mst_info {
|
||||
bool draw_distortion;
|
||||
|
||||
mst_info() : primary_bitmap(-1), primary_glow_bitmap(-1), secondary_glow_bitmap(-1), tertiary_glow_bitmap(-1), distortion_bitmap(-1),
|
||||
use_ab(false), glow_noise(1.0f), rotvel(NULL), length(vmd_zero_vector), glow_rad_factor(1.0f),
|
||||
use_ab(false), glow_noise(1.0f), rotvel(vmd_zero_vector), length(vmd_zero_vector), glow_rad_factor(1.0f),
|
||||
secondary_glow_rad_factor(1.0f), tertiary_glow_rad_factor(1.0f), glow_length_factor(1.0f), distortion_rad_factor(1.0f), distortion_length_factor(1.0f),
|
||||
draw_distortion(true)
|
||||
{}
|
||||
} mst_info;
|
||||
|
||||
|
||||
//Valathil - Buffer struct for transparent object sorting
|
||||
typedef struct transparent_object {
|
||||
int blend_filter;
|
||||
float alpha;
|
||||
int texture;
|
||||
int glow_map;
|
||||
int spec_map;
|
||||
int norm_map;
|
||||
int height_map;
|
||||
int misc_map;
|
||||
vertex_buffer *buffer;
|
||||
unsigned int tmap_flags;
|
||||
int i;
|
||||
vec3d scale;
|
||||
} transparent_object;
|
||||
|
||||
typedef struct transparent_submodel {
|
||||
bsp_info *model;
|
||||
matrix orient;
|
||||
bool is_submodel;
|
||||
bool pop_matrix;
|
||||
SCP_vector<transparent_object> transparent_objects;
|
||||
} transparent_submodel;
|
||||
// scale the engines thrusters by this much
|
||||
// Only enabled if MR_SHOW_THRUSTERS is on
|
||||
void model_set_thrust(int model_num = -1, mst_info *mst = NULL);
|
||||
@@ -1278,4 +1356,37 @@ void model_finish_cloak(int full_cloak);
|
||||
void model_do_look_at(int model_num); //Bobboau
|
||||
|
||||
void model_do_dumb_rotation(int modelnum); //Bobboau
|
||||
|
||||
int model_should_render_engine_glow(int objnum, int bank_obj);
|
||||
|
||||
void model_interp_set_clip_plane(vec3d* pos = NULL, vec3d* normal = NULL);
|
||||
|
||||
void model_interp_set_animated_effect_and_timer(int effect_num = 0, float effect_timer = 0.0f);
|
||||
|
||||
bool model_get_team_color(team_color *clr, const SCP_string &team, const SCP_string &secondaryteam, fix timestamp, int fadetime);
|
||||
|
||||
void model_interp_set_team_color(const SCP_string &team, const SCP_string &secondaryteam, fix timestamp, int fadetime);
|
||||
|
||||
void moldel_calc_facing_pts( vec3d *top, vec3d *bot, vec3d *fvec, vec3d *pos, float w, float z_add, vec3d *Eyeposition );
|
||||
|
||||
void interp_render_arc(vec3d *v1, vec3d *v2, color *primary, color *secondary, float arc_width);
|
||||
|
||||
void model_render_insignias(polymodel *pm, int detail_level, int bitmap_num);
|
||||
|
||||
void model_draw_debug_points( polymodel *pm, bsp_info * submodel, uint flags );
|
||||
|
||||
void model_render_shields( polymodel * pm, uint flags );
|
||||
|
||||
void model_draw_paths( int model_num, uint flags );
|
||||
|
||||
void model_draw_paths_htl( int model_num, uint flags );
|
||||
|
||||
void model_draw_bay_paths(int model_num);
|
||||
|
||||
void model_draw_bay_paths_htl(int model_num);
|
||||
|
||||
void glowpoint_init();
|
||||
SCP_vector<glow_point_bank_override>::iterator get_glowpoint_bank_override_by_name(const char* name);
|
||||
extern SCP_vector<glow_point_bank_override> glowpoint_bank_overrides;
|
||||
|
||||
#endif // _MODEL_H
|
||||
@@ -377,6 +377,8 @@ int model_collide_parse_bsp_defpoints(ubyte * p)
|
||||
ubyte * normcount = p+20;
|
||||
vec3d *src = vp(p+offset);
|
||||
|
||||
model_collide_allocate_point_list(nverts);
|
||||
|
||||
Assert( Mc_point_list != NULL );
|
||||
|
||||
for (n=0; n<nverts; n++ ) {
|
||||
@@ -1373,7 +1375,7 @@ void model_collide_preprocess_subobj(vec3d *pos, matrix *orient, polymodel *pm,
|
||||
}
|
||||
}
|
||||
|
||||
void model_collide_preprocess(matrix *orient, int model_instance_num)
|
||||
void model_collide_preprocess(matrix *orient, int model_instance_num, int detail_num)
|
||||
{
|
||||
polymodel_instance *pmi;
|
||||
polymodel *pm;
|
||||
@@ -1381,10 +1383,12 @@ void model_collide_preprocess(matrix *orient, int model_instance_num)
|
||||
pmi = model_get_instance(model_instance_num);
|
||||
pm = model_get(pmi->model_num);
|
||||
|
||||
matrix current_orient = *orient;
|
||||
matrix current_orient;
|
||||
vec3d current_pos;
|
||||
|
||||
current_orient = *orient;
|
||||
|
||||
vm_vec_zero(¤t_pos);
|
||||
|
||||
model_collide_preprocess_subobj(¤t_pos, ¤t_orient, pm, pmi, pm->detail[0]);
|
||||
model_collide_preprocess_subobj(¤t_pos, ¤t_orient, pm, pmi, pm->detail[detail_num]);
|
||||
}
|
||||
+1054
-317
File diff suppressed because it is too large.
Load diff
+404
-16
@@ -61,6 +61,7 @@ SCP_vector<bsp_collision_tree> Bsp_collision_tree_list;
|
||||
|
||||
static int model_initted = 0;
|
||||
extern int Cmdline_nohtl;
|
||||
extern int Use_GLSL;
|
||||
|
||||
#ifndef NDEBUG
|
||||
CFILE *ss_fp = NULL; // file pointer used to dump subsystem information
|
||||
@@ -84,7 +85,9 @@ static uint Global_checksum = 0;
|
||||
static int Model_signature = 0;
|
||||
|
||||
void interp_configure_vertex_buffers(polymodel*, int);
|
||||
void interp_pack_vertex_buffers(polymodel*, int);
|
||||
void interp_pack_vertex_buffers(polymodel* pm, int mn);
|
||||
void interp_create_detail_index_buffer(polymodel *pm, int detail);
|
||||
void interp_create_transparency_index_buffer(polymodel *pm, int detail_num);
|
||||
|
||||
void model_set_subsys_path_nums(polymodel *pm, int n_subsystems, model_subsystem *subsystems);
|
||||
void model_set_bay_path_nums(polymodel *pm);
|
||||
@@ -121,6 +124,8 @@ flag_def_list Dock_type_names[] =
|
||||
|
||||
int Num_dock_type_names = sizeof(Dock_type_names) / sizeof(flag_def_list);
|
||||
|
||||
SCP_vector<glow_point_bank_override> glowpoint_bank_overrides;
|
||||
|
||||
// Free up a model, getting rid of all its memory
|
||||
// With the basic page in system this can be called from outside of modelread.cpp
|
||||
void model_unload(int modelnum, int force)
|
||||
@@ -262,6 +267,10 @@ void model_unload(int modelnum, int force)
|
||||
vm_free(pm->shield_collision_tree);
|
||||
}
|
||||
|
||||
for ( int i = 0; i < MAX_MODEL_DETAIL_LEVELS; ++i ) {
|
||||
pm->detail_buffers[i].clear();
|
||||
}
|
||||
|
||||
// run through Ship_info[] and if the model has been loaded we'll need to reset the modelnum to -1.
|
||||
for (i = 0; i < Num_ship_classes; i++) {
|
||||
if ( pm->id == Ship_info[i].model_num ) {
|
||||
@@ -825,7 +834,7 @@ void create_vertex_buffer(polymodel *pm)
|
||||
for (i = 0; i < pm->n_models; i++) {
|
||||
interp_configure_vertex_buffers(pm, i);
|
||||
}
|
||||
|
||||
|
||||
// these must be reset to NULL for the tests to work correctly later
|
||||
if (ibuffer_info.read != NULL) {
|
||||
cfclose( ibuffer_info.read );
|
||||
@@ -837,12 +846,62 @@ void create_vertex_buffer(polymodel *pm)
|
||||
|
||||
memset( &ibuffer_info, 0, sizeof(IBX) );
|
||||
|
||||
// figure out which vertices are transparent
|
||||
for ( i = 0; i < pm->n_models; i++ ) {
|
||||
if ( !pm->submodel[i].is_thruster ) {
|
||||
interp_create_transparency_index_buffer(pm, i);
|
||||
}
|
||||
}
|
||||
|
||||
bool use_batched_rendering = true;
|
||||
|
||||
if ( Use_GLSL >= 3 && !Cmdline_no_batching ) {
|
||||
bool unequal_stride = false;
|
||||
uint stride = 0;
|
||||
|
||||
// figure out if the vertex stride of this entire model matches. if not, turn off batched rendering for this model
|
||||
for ( i = 0; i < pm->n_models; ++i ) {
|
||||
if ( pm->submodel[i].buffer.model_list != NULL && pm->submodel[i].buffer.stride != stride) {
|
||||
if ( stride == 0 ) {
|
||||
stride = pm->submodel[i].buffer.stride;
|
||||
} else {
|
||||
use_batched_rendering = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
use_batched_rendering = false;
|
||||
}
|
||||
|
||||
// create another set of indexes for the detail buffers
|
||||
if ( use_batched_rendering ) {
|
||||
for ( i = 0; i < pm->n_detail_levels; i++ ) {
|
||||
interp_create_detail_index_buffer(pm, i);
|
||||
}
|
||||
}
|
||||
|
||||
// now actually fill the buffer with our info ...
|
||||
for (i = 0; i < pm->n_models; i++) {
|
||||
interp_pack_vertex_buffers(pm, i);
|
||||
|
||||
// release temporary memory
|
||||
pm->submodel[i].buffer.release();
|
||||
pm->submodel[i].trans_buffer.release();
|
||||
}
|
||||
|
||||
if ( use_batched_rendering ) {
|
||||
// pack the merged index buffers to the vbo.
|
||||
for ( i = 0; i < pm->n_detail_levels; ++i ) {
|
||||
if ( pm->detail_buffers[i].model_list == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gr_pack_buffer(pm->vertex_buffer_id, &pm->detail_buffers[i]);
|
||||
pm->detail_buffers[i].release();
|
||||
}
|
||||
|
||||
pm->flags |= PM_FLAG_BATCHED;
|
||||
}
|
||||
|
||||
// ... and then finalize buffer
|
||||
@@ -1232,7 +1291,7 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs
|
||||
// Check for unrealistic radii
|
||||
if ( pm->submodel[n].rad <= 0.1f )
|
||||
{
|
||||
Warning(LOCATION, "Submodel <%s> in model <%s> has a radius <= 0.1f\n", pm->submodel[n].name, filename);
|
||||
//Warning(LOCATION, "Submodel <%s> in model <%s> has a radius <= 0.1f\n", pm->submodel[n].name, filename);
|
||||
}
|
||||
|
||||
// sanity first!
|
||||
@@ -1805,8 +1864,8 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs
|
||||
if (bank->num_points > 0)
|
||||
bank->points = (glow_point *) vm_malloc(sizeof(glow_point) * bank->num_points);
|
||||
|
||||
if ((bank->off_time > 0) && (bank->disp_time > 0))
|
||||
bank->is_on = false;
|
||||
//if((bank->off_time > 0) && (bank->disp_time > 0))
|
||||
//bank->is_on = false;
|
||||
|
||||
cfread_string_len(props, MAX_PROP_LEN, fp);
|
||||
// look for $glow_texture=xxx
|
||||
@@ -2408,24 +2467,52 @@ void model_load_texture(polymodel *pm, int i, char *file)
|
||||
int shader_flags = 0;
|
||||
|
||||
if (tbase->GetTexture() > 0)
|
||||
shader_flags |= SDR_FLAG_DIFFUSE_MAP;
|
||||
shader_flags |= SDR_FLAG_MODEL_DIFFUSE_MAP;
|
||||
if (tglow->GetTexture() > 0 && Cmdline_glow)
|
||||
shader_flags |= SDR_FLAG_GLOW_MAP;
|
||||
shader_flags |= SDR_FLAG_MODEL_GLOW_MAP;
|
||||
if (tspec->GetTexture() > 0 && Cmdline_spec)
|
||||
shader_flags |= SDR_FLAG_SPEC_MAP;
|
||||
shader_flags |= SDR_FLAG_MODEL_SPEC_MAP;
|
||||
if (tnorm->GetTexture() > 0 && Cmdline_normal)
|
||||
shader_flags |= SDR_FLAG_NORMAL_MAP;
|
||||
shader_flags |= SDR_FLAG_MODEL_NORMAL_MAP;
|
||||
if (theight->GetTexture() > 0 && Cmdline_height)
|
||||
shader_flags |= SDR_FLAG_HEIGHT_MAP;
|
||||
shader_flags |= SDR_FLAG_MODEL_HEIGHT_MAP;
|
||||
if (tspec->GetTexture() > 0 && Cmdline_env && Cmdline_spec) // No env maps without spec map
|
||||
shader_flags |= SDR_FLAG_ENV_MAP;
|
||||
shader_flags |= SDR_FLAG_MODEL_ENV_MAP;
|
||||
if (tmisc->GetTexture() > 0)
|
||||
shader_flags |= SDR_FLAG_MISC_MAP;
|
||||
shader_flags |= SDR_FLAG_MODEL_MISC_MAP;
|
||||
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, SDR_FLAG_MODEL_SHADOW_MAP);
|
||||
|
||||
gr_maybe_create_shader(shader_flags | SDR_FLAG_LIGHT);
|
||||
gr_maybe_create_shader(shader_flags | SDR_FLAG_LIGHT | SDR_FLAG_FOG);
|
||||
gr_maybe_create_shader(shader_flags | SDR_FLAG_LIGHT | SDR_FLAG_ANIMATED);
|
||||
gr_maybe_create_shader(shader_flags | SDR_FLAG_LIGHT | SDR_FLAG_ANIMATED | SDR_FLAG_FOG);
|
||||
if(Use_GLSL > 1)
|
||||
shader_flags |= SDR_FLAG_MODEL_CLIP;
|
||||
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT | SDR_FLAG_MODEL_ANIMATED);
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT | SDR_FLAG_MODEL_ANIMATED | SDR_FLAG_MODEL_FOG);
|
||||
|
||||
if(Use_GLSL > 1)
|
||||
shader_flags |= SDR_FLAG_MODEL_DEFERRED;
|
||||
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT);
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT | SDR_FLAG_MODEL_FOG);
|
||||
|
||||
if( !Cmdline_no_batching && Use_GLSL >= 3 ) {
|
||||
shader_flags &= ~SDR_FLAG_MODEL_DEFERRED;
|
||||
shader_flags |= SDR_FLAG_MODEL_TRANSFORM;
|
||||
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT | SDR_FLAG_MODEL_ANIMATED);
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT | SDR_FLAG_MODEL_ANIMATED | SDR_FLAG_MODEL_FOG);
|
||||
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT);
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT | SDR_FLAG_MODEL_FOG);
|
||||
|
||||
shader_flags |= SDR_FLAG_MODEL_DEFERRED;
|
||||
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT | SDR_FLAG_MODEL_ANIMATED);
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT | SDR_FLAG_MODEL_ANIMATED | SDR_FLAG_MODEL_FOG);
|
||||
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT);
|
||||
gr_maybe_create_shader(SDR_TYPE_MODEL, shader_flags | SDR_FLAG_MODEL_LIGHT | SDR_FLAG_MODEL_FOG);
|
||||
}
|
||||
}
|
||||
|
||||
//returns the number of this model
|
||||
@@ -2717,6 +2804,7 @@ int model_create_instance(int model_num, int submodel_num)
|
||||
}
|
||||
|
||||
polymodel_instance *pmi = (polymodel_instance*)vm_malloc(sizeof(polymodel_instance));
|
||||
memset(pmi, 0, sizeof(polymodel_instance));
|
||||
|
||||
// if not found, create a slot
|
||||
if ( open_slot < 0 ) {
|
||||
@@ -2729,9 +2817,11 @@ int model_create_instance(int model_num, int submodel_num)
|
||||
polymodel *pm = model_get(model_num);
|
||||
|
||||
pmi->submodel = (submodel_instance*)vm_malloc( sizeof(submodel_instance)*pm->n_models );
|
||||
pmi->submodel_render = (submodel_instance*)vm_malloc( sizeof(submodel_instance)*pm->n_models );
|
||||
|
||||
for ( i = 0; i < pm->n_models; i++ ) {
|
||||
model_clear_submodel_instance( &pmi->submodel[i] );
|
||||
model_clear_submodel_instance( &pmi->submodel_render[i] );
|
||||
}
|
||||
|
||||
pmi->model_num = model_num;
|
||||
@@ -2758,6 +2848,10 @@ void model_delete_instance(int model_instance_num)
|
||||
vm_free(pmi->submodel);
|
||||
}
|
||||
|
||||
if ( pmi->submodel_render ) {
|
||||
vm_free(pmi->submodel_render);
|
||||
}
|
||||
|
||||
vm_free(pmi);
|
||||
|
||||
Polygon_model_instances[model_instance_num] = NULL;
|
||||
@@ -4383,6 +4477,20 @@ void model_get_rotating_submodel_list(SCP_vector<int> *submodel_vector, object *
|
||||
|
||||
}
|
||||
|
||||
void model_get_submodel_tree_list(SCP_vector<int> &submodel_vector, polymodel* pm, int mn)
|
||||
{
|
||||
if ( pm->submodel[mn].buffer.model_list != NULL ) {
|
||||
submodel_vector.push_back(mn);
|
||||
}
|
||||
|
||||
int i = pm->submodel[mn].first_child;
|
||||
|
||||
while ( i >= 0 ) {
|
||||
model_get_submodel_tree_list(submodel_vector, pm, i);
|
||||
|
||||
i = pm->submodel[i].next_sibling;
|
||||
}
|
||||
}
|
||||
|
||||
// Given a direction (pnt) that is in sub_model_num's frame of
|
||||
// reference, and given the object's orient and position,
|
||||
@@ -4530,6 +4638,7 @@ void model_clear_submodel_instance( submodel_instance *sm_instance )
|
||||
sm_instance->angs.h = 0.0f;
|
||||
sm_instance->blown_off = false;
|
||||
sm_instance->collision_checked = false;
|
||||
sm_instance->moved_this_frame = false;
|
||||
}
|
||||
|
||||
void model_clear_submodel_instances( int model_instance_num )
|
||||
@@ -4654,6 +4763,7 @@ void model_update_instance(int model_instance_num, int sub_model_num, submodel_i
|
||||
if ( sub_model_num >= pm->n_models ) return;
|
||||
|
||||
submodel_instance *smi = &pmi->submodel[sub_model_num];
|
||||
submodel_instance *smi_r = &pmi->submodel_render[sub_model_num];
|
||||
bsp_info *sm = &pm->submodel[sub_model_num];
|
||||
|
||||
// Set the "blown out" flags
|
||||
@@ -4664,12 +4774,17 @@ void model_update_instance(int model_instance_num, int sub_model_num, submodel_i
|
||||
pmi->submodel[sm->my_replacement].blown_off = false;
|
||||
pmi->submodel[sm->my_replacement].angs = sii->angs;
|
||||
pmi->submodel[sm->my_replacement].prev_angs = sii->prev_angs;
|
||||
|
||||
pmi->submodel_render[sm->my_replacement].blown_off = false;
|
||||
pmi->submodel_render[sm->my_replacement].angs = sii->angs;
|
||||
pmi->submodel_render[sm->my_replacement].prev_angs = sii->prev_angs;
|
||||
}
|
||||
} else {
|
||||
// If submodel isn't yet blown off and has a -destroyed replacement model, we prevent
|
||||
// the replacement model from being drawn by marking it as having been blown off
|
||||
if ( sm->my_replacement > -1 && sm->my_replacement != sub_model_num) {
|
||||
pmi->submodel[sm->my_replacement].blown_off = true;
|
||||
pmi->submodel_render[sm->my_replacement].blown_off = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4677,6 +4792,11 @@ void model_update_instance(int model_instance_num, int sub_model_num, submodel_i
|
||||
smi->angs = sii->angs;
|
||||
smi->prev_angs = sii->prev_angs;
|
||||
|
||||
smi_r->angs = sii->angs;
|
||||
smi_r->prev_angs = sii->prev_angs;
|
||||
|
||||
smi->moved_this_frame = true;
|
||||
|
||||
// For all the detail levels of this submodel, set them also.
|
||||
for (i=0; i<sm->num_details; i++ ) {
|
||||
model_update_instance(model_instance_num, sm->details[i], sii );
|
||||
@@ -4689,24 +4809,30 @@ void model_instance_dumb_rotation_sub(polymodel_instance * pmi, polymodel *pm, i
|
||||
|
||||
bsp_info * sm = &pm->submodel[mn];
|
||||
submodel_instance *smi = &pmi->submodel[mn];
|
||||
submodel_instance *smi_r = &pmi->submodel_render[mn];
|
||||
|
||||
if ( sm->movement_type == MSS_FLAG_DUM_ROTATES ){
|
||||
float *ang;
|
||||
float *ang_r;
|
||||
int axis = sm->movement_axis;
|
||||
switch ( axis ) {
|
||||
case MOVEMENT_AXIS_X:
|
||||
ang = &smi->angs.p;
|
||||
ang_r = &smi_r->angs.p;
|
||||
break;
|
||||
case MOVEMENT_AXIS_Z:
|
||||
ang = &smi->angs.b;
|
||||
ang_r = &smi_r->angs.b;
|
||||
break;
|
||||
default:
|
||||
case MOVEMENT_AXIS_Y:
|
||||
ang = &smi->angs.h;
|
||||
ang_r = &smi_r->angs.h;
|
||||
break;
|
||||
}
|
||||
*ang = sm->dumb_turn_rate * float(timestamp())/1000.0f;
|
||||
*ang = ((*ang/(PI*2.0f))-float(int(*ang/(PI*2.0f))))*(PI*2.0f);
|
||||
*ang_r = *ang;
|
||||
//this keeps ang from getting bigger than 2PI
|
||||
}
|
||||
|
||||
@@ -5371,3 +5497,265 @@ void swap_sldc_data(ubyte *buffer)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void glowpoint_override_defaults(glow_point_bank_override *gpo)
|
||||
{
|
||||
gpo->name[0] = 0;
|
||||
gpo->type = 0;
|
||||
gpo->on_time = 0;
|
||||
gpo->off_time = 0;
|
||||
gpo->disp_time = 0;
|
||||
gpo->glow_bitmap = -1;
|
||||
gpo->glow_neb_bitmap = -1;
|
||||
gpo->is_on = true;
|
||||
gpo->type_override = false;
|
||||
gpo->on_time_override = false;
|
||||
gpo->off_time_override = false;
|
||||
gpo->disp_time_override = false;
|
||||
gpo->glow_bitmap_override = false;
|
||||
gpo->pulse_period_override = false;
|
||||
gpo->pulse_type = 0;
|
||||
gpo->pulse_period = 0;
|
||||
gpo->pulse_amplitude = 1.0f;
|
||||
gpo->pulse_bias = 0.0f;
|
||||
gpo->pulse_exponent = 1.0f;
|
||||
gpo->is_lightsource = false;
|
||||
gpo->radius_multi = 15.0f;
|
||||
gpo->light_color = vmd_zero_vector;
|
||||
gpo->light_mix_color = vmd_zero_vector;
|
||||
gpo->lightcone = false;
|
||||
gpo->cone_angle = 90.0f;
|
||||
gpo->cone_direction = vmd_zero_vector;
|
||||
gpo->dualcone = false;
|
||||
gpo->rotating = false;
|
||||
gpo->rotation_axis = vmd_zero_vector;
|
||||
gpo->rotation_speed = 0.0f;
|
||||
}
|
||||
|
||||
SCP_vector<glow_point_bank_override>::iterator get_glowpoint_bank_override_by_name(const char* name)
|
||||
{
|
||||
SCP_vector<glow_point_bank_override>::iterator gpo = glowpoint_bank_overrides.begin();
|
||||
for(;gpo != glowpoint_bank_overrides.end(); ++gpo) {
|
||||
if(!strcmp(gpo->name, name)) {
|
||||
return gpo;
|
||||
}
|
||||
}
|
||||
return glowpoint_bank_overrides.end();
|
||||
}
|
||||
|
||||
void parse_glowpoint_table(const char *filename)
|
||||
{
|
||||
int rval;
|
||||
|
||||
|
||||
if ( (rval = setjmp(parse_abort)) != 0 ) {
|
||||
mprintf(("Unable to parse '%s'! Error code = %d.\n", filename, rval));
|
||||
return;
|
||||
}
|
||||
|
||||
if (cf_exists_full(filename, CF_TYPE_TABLES))
|
||||
read_file_text(filename, CF_TYPE_TABLES);
|
||||
else
|
||||
return;
|
||||
|
||||
reset_parse();
|
||||
|
||||
if (optional_string("#Glowpoint overrides")) {
|
||||
while ( !required_string_either("$Name:", "#End") ) {
|
||||
glow_point_bank_override gpo;
|
||||
glowpoint_override_defaults(&gpo);
|
||||
|
||||
bool replace = false;
|
||||
bool skip = false;
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string(gpo.name, F_NAME, NAME_LENGTH);
|
||||
|
||||
if(optional_string("+nocreate")) {
|
||||
if(Parsing_modular_table) {
|
||||
replace = true;
|
||||
} else {
|
||||
mprintf(("+nocreate specified in non-modular glowpoint table.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
if(optional_string("$On:")) {
|
||||
stuff_boolean(&gpo.is_on);
|
||||
}
|
||||
|
||||
if(optional_string("$Displacement time:")) {
|
||||
stuff_int(&gpo.disp_time);
|
||||
gpo.disp_time_override = true;
|
||||
}
|
||||
|
||||
if(optional_string("$On time:")) {
|
||||
stuff_int(&gpo.on_time);
|
||||
gpo.on_time_override = true;
|
||||
}
|
||||
|
||||
if(optional_string("$Off time:")) {
|
||||
stuff_int(&gpo.off_time);
|
||||
gpo.off_time_override = true;
|
||||
}
|
||||
|
||||
if(optional_string("$Texture:")) {
|
||||
char glow_texture_name[32];
|
||||
stuff_string(glow_texture_name, F_NAME, NAME_LENGTH);
|
||||
|
||||
gpo.glow_bitmap_override = true;
|
||||
|
||||
if(stricmp(glow_texture_name, "none")) {
|
||||
gpo.glow_bitmap = bm_load(glow_texture_name);
|
||||
|
||||
if (gpo.glow_bitmap < 0)
|
||||
{
|
||||
Warning( LOCATION, "Couldn't open texture '%s'\nreferenced by glowpoint present '%s'\n", glow_texture_name, gpo.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
nprintf(( "Model", "Glowpoint preset %s texture num is %d\n", gpo.name, gpo.glow_bitmap));
|
||||
}
|
||||
|
||||
char glow_texture_neb_name[256];
|
||||
strncpy(glow_texture_neb_name, glow_texture_name, 256);
|
||||
strcat(glow_texture_neb_name, "-neb");
|
||||
gpo.glow_neb_bitmap = bm_load(glow_texture_neb_name);
|
||||
|
||||
if (gpo.glow_neb_bitmap < 0)
|
||||
{
|
||||
gpo.glow_neb_bitmap = gpo.glow_bitmap;
|
||||
nprintf(( "Model", "Glowpoint preset nebula texture not found for '%s', using normal glowpoint texture instead\n", gpo.name));
|
||||
}
|
||||
else
|
||||
{
|
||||
nprintf(( "Model", "Glowpoint preset %s nebula texture num is %d\n", gpo, gpo.glow_neb_bitmap));
|
||||
}
|
||||
} else {
|
||||
gpo.glow_bitmap_override = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(optional_string("$Type:")) {
|
||||
stuff_int(&gpo.type);
|
||||
gpo.type_override = true;
|
||||
}
|
||||
|
||||
if(optional_string("$Pulse type:")) {
|
||||
char pulsetype[33];
|
||||
stuff_string(pulsetype, F_NAME, NAME_LENGTH);
|
||||
if(!stricmp(pulsetype, "sine")) {
|
||||
gpo.pulse_type = PULSE_SIN;
|
||||
} else if(!stricmp(pulsetype, "cosine")) {
|
||||
gpo.pulse_type = PULSE_COS;
|
||||
} else if(!stricmp(pulsetype, "triangle")) {
|
||||
gpo.pulse_type = PULSE_TRI;
|
||||
} else if(!stricmp(pulsetype, "shiftedtriangle")) {
|
||||
gpo.pulse_type = PULSE_SHIFTTRI;
|
||||
}
|
||||
}
|
||||
|
||||
if(optional_string("$Pulse period:")) {
|
||||
stuff_int(&gpo.pulse_period);
|
||||
gpo.pulse_period_override = true;
|
||||
}
|
||||
|
||||
if(optional_string("$Pulse amplitude:")) {
|
||||
stuff_float(&gpo.pulse_amplitude);
|
||||
}
|
||||
|
||||
if(optional_string("$Pulse bias:")) {
|
||||
stuff_float(&gpo.pulse_bias);
|
||||
}
|
||||
|
||||
if(optional_string("$Pulse exponent:")) {
|
||||
stuff_float(&gpo.pulse_exponent);
|
||||
}
|
||||
|
||||
if(optional_string("+light")) {
|
||||
gpo.is_lightsource = true;
|
||||
|
||||
if(optional_string("$Light radius multiplier:")) {
|
||||
stuff_float(&gpo.radius_multi);
|
||||
}
|
||||
|
||||
required_string("$Light color:");
|
||||
int temp;
|
||||
stuff_int(&temp);
|
||||
gpo.light_color.xyz.x = temp / 255.0f;
|
||||
stuff_int(&temp);
|
||||
gpo.light_color.xyz.y = temp / 255.0f;
|
||||
stuff_int(&temp);
|
||||
gpo.light_color.xyz.z = temp / 255.0f;
|
||||
|
||||
if(optional_string("$Light mix color:")) {
|
||||
stuff_int(&temp);
|
||||
gpo.light_mix_color.xyz.x = temp / 255.0f;
|
||||
stuff_int(&temp);
|
||||
gpo.light_mix_color.xyz.y = temp / 255.0f;
|
||||
stuff_int(&temp);
|
||||
gpo.light_mix_color.xyz.z = temp / 255.0f;
|
||||
}
|
||||
|
||||
if(optional_string("+lightcone")) {
|
||||
gpo.lightcone = true;
|
||||
|
||||
if(optional_string("$Cone angle:")) {
|
||||
stuff_float(&gpo.cone_angle);
|
||||
gpo.cone_inner_angle = cos((gpo.cone_angle - (gpo.cone_angle<20.0f)?gpo.cone_angle*0.5f:20.0f) / 180.0f * PI);
|
||||
gpo.cone_angle = cos(gpo.cone_angle / 180.0f * PI);
|
||||
}
|
||||
|
||||
required_string("$Cone direction:");
|
||||
stuff_float_list(gpo.cone_direction.a1d, 3);
|
||||
if(vm_vec_mag_quick(&gpo.cone_direction) != 0.0f) {
|
||||
vm_vec_normalize(&gpo.cone_direction);
|
||||
} else {
|
||||
Warning(LOCATION, "Null vector specified in cone direction for glowpoint override %s. Discarding preset.", gpo.name);
|
||||
skip = true;
|
||||
}
|
||||
if(optional_string("+dualcone")) {
|
||||
gpo.dualcone = true;
|
||||
}
|
||||
|
||||
if(optional_string("+rotating")) {
|
||||
gpo.rotating = true;
|
||||
required_string("$Rotation axis:");
|
||||
stuff_float_list(gpo.rotation_axis.a1d, 3);
|
||||
if(vm_vec_mag_quick(&gpo.rotation_axis) != 0.0f) {
|
||||
vm_vec_normalize(&gpo.rotation_axis);
|
||||
} else {
|
||||
Warning(LOCATION, "Null vector specified in rotation axis for glowpoint override %s. Discarding preset.", gpo.name);
|
||||
skip = true;
|
||||
}
|
||||
required_string("$Rotation speed:");
|
||||
stuff_float(&gpo.rotation_speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!skip) {
|
||||
SCP_vector<glow_point_bank_override>::iterator gpoi = get_glowpoint_bank_override_by_name(gpo.name);
|
||||
if(gpoi == glowpoint_bank_overrides.end()) {
|
||||
if(!replace) {
|
||||
glowpoint_bank_overrides.push_back(gpo);
|
||||
}
|
||||
} else {
|
||||
if(!replace) {
|
||||
Warning(LOCATION, "+nocreate not specified for glowpoint override that already exists. Discarding duplicate entry: %s", gpo.name);
|
||||
} else {
|
||||
glowpoint_bank_overrides.erase(gpoi);
|
||||
glowpoint_bank_overrides.push_back(gpo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
required_string("#End");
|
||||
}
|
||||
}
|
||||
|
||||
void glowpoint_init()
|
||||
{
|
||||
glowpoint_bank_overrides.clear();
|
||||
parse_glowpoint_table("glowpoints.tbl");
|
||||
parse_modular_table(NOX("*-gpo.tbm"), parse_glowpoint_table);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* 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 "model/model.h"
|
||||
#include "math/vecmat.h"
|
||||
#include "lighting/lighting.h"
|
||||
#include "graphics/gropengltnl.h"
|
||||
|
||||
extern light Lights[MAX_LIGHTS];
|
||||
extern int Num_lights;
|
||||
|
||||
extern bool Rendering_to_shadow_map;
|
||||
|
||||
extern matrix Object_matrix;
|
||||
extern vec3d Object_position;
|
||||
|
||||
extern team_color* Current_team_color;
|
||||
|
||||
inline int in_box(vec3d *min, vec3d *max, vec3d *pos, vec3d *view_pos)
|
||||
{
|
||||
vec3d point;
|
||||
|
||||
vm_vec_sub(&point, view_pos, 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_pos)
|
||||
{
|
||||
if ( vm_vec_dist(view_pos, pos) <= radius )
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern int model_interp_get_texture(texture_info *tinfo, fix base_frametime);
|
||||
|
||||
struct transform
|
||||
{
|
||||
matrix basis;
|
||||
vec3d origin;
|
||||
|
||||
transform(): basis(vmd_identity_matrix), origin(vmd_zero_vector) {}
|
||||
transform(matrix *m, vec3d *v): basis(*m), origin(*v) {}
|
||||
};
|
||||
|
||||
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 Outline_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;
|
||||
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_outline_color(color &clr);
|
||||
void set_outline_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);
|
||||
|
||||
bool is_clip_plane_set();
|
||||
bool is_team_color_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_outline_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();
|
||||
};
|
||||
|
||||
struct clip_plane_state
|
||||
{
|
||||
vec3d normal;
|
||||
vec3d point;
|
||||
};
|
||||
|
||||
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
|
||||
int clip_plane;
|
||||
};
|
||||
|
||||
struct render_state
|
||||
{
|
||||
int clip_plane_handle;
|
||||
int texture_addressing;
|
||||
int fill_mode;
|
||||
int cull_mode;
|
||||
int center_alpha;
|
||||
int zbias;
|
||||
int buffer_id;
|
||||
|
||||
float animated_timer;
|
||||
int animated_effect;
|
||||
|
||||
bool lighting;
|
||||
light_indexing_info lights;
|
||||
float light_factor;
|
||||
|
||||
float thrust_scale;
|
||||
|
||||
bool using_team_color;
|
||||
team_color tm_color;
|
||||
color clr;
|
||||
|
||||
// fog state maybe shouldn't belong here. if we have fog, then it's probably occurring for all objects in scene.
|
||||
int fog_mode;
|
||||
int r;
|
||||
int g;
|
||||
int b;
|
||||
float fog_near;
|
||||
float fog_far;
|
||||
|
||||
render_state()
|
||||
{
|
||||
clip_plane_handle = -1;
|
||||
texture_addressing = TMAP_ADDRESS_WRAP;
|
||||
fill_mode = GR_FILL_MODE_SOLID;
|
||||
|
||||
buffer_id = -1;
|
||||
|
||||
lighting = false;
|
||||
|
||||
fog_mode = GR_FOGMODE_NONE;
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
fog_near = -1.0f;
|
||||
fog_far = -1.0f;
|
||||
|
||||
lights.index_start = 0;
|
||||
lights.num_lights = 0;
|
||||
light_factor = 1.0f;
|
||||
|
||||
animated_timer = 0.0f;
|
||||
animated_effect = 0;
|
||||
|
||||
thrust_scale = -1.0f;
|
||||
|
||||
gr_init_color(&clr, 255, 255, 255);
|
||||
}
|
||||
};
|
||||
|
||||
struct queued_buffer_draw
|
||||
{
|
||||
int render_state_handle;
|
||||
int texture_maps[TM_NUM_TYPES];
|
||||
int transform_buffer_offset;
|
||||
|
||||
color clr;
|
||||
int blend_filter;
|
||||
float alpha;
|
||||
int depth_mode;
|
||||
|
||||
transform transformation;
|
||||
vec3d scale;
|
||||
|
||||
vertex_buffer *buffer;
|
||||
int texi;
|
||||
int flags;
|
||||
int sdr_flags;
|
||||
|
||||
float thrust_scale;
|
||||
|
||||
queued_buffer_draw()
|
||||
{
|
||||
depth_mode = GR_ZBUFF_FULL;
|
||||
|
||||
texture_maps[TM_BASE_TYPE] = -1;
|
||||
texture_maps[TM_GLOW_TYPE] = -1;
|
||||
texture_maps[TM_HEIGHT_TYPE] = -1;
|
||||
texture_maps[TM_MISC_TYPE] = -1;
|
||||
texture_maps[TM_NORMAL_TYPE] = -1;
|
||||
texture_maps[TM_SPECULAR_TYPE] = -1;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
uint Mem_alloc_size;
|
||||
|
||||
int Current_offset;
|
||||
|
||||
void allocate_memory();
|
||||
public:
|
||||
model_batch_buffer() : Mem_alloc(NULL), Mem_alloc_size(0), Current_offset(0) {};
|
||||
|
||||
void reset();
|
||||
|
||||
int 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;
|
||||
|
||||
render_state Current_render_state;
|
||||
bool Dirty_render_state;
|
||||
|
||||
scene_lights Scene_light_handler;
|
||||
|
||||
int Current_textures[TM_NUM_TYPES];
|
||||
int Current_blend_filter;
|
||||
float Current_alpha;
|
||||
int Current_depth_mode;
|
||||
|
||||
int Current_set_clip_plane;
|
||||
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);
|
||||
uint determine_shader_flags(render_state *state, queued_buffer_draw *draw_info, vertex_buffer *buffer, int tmap_flags);
|
||||
|
||||
SCP_vector<clip_plane_state> Clip_planes;
|
||||
SCP_vector<render_state> Render_states;
|
||||
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 reset_state();
|
||||
void set_clip_plane(const vec3d &position, const vec3d &normal);
|
||||
void set_clip_plane();
|
||||
void set_thrust_scale(float scale = -1.0f);
|
||||
void set_texture(int texture_type, int texture_handle);
|
||||
void set_depth_mode(int depth_set);
|
||||
void set_blend_filter(int filter, float alpha);
|
||||
void set_texture_addressing(int addressing);
|
||||
void set_fog(int fog_mode, int r, int g, int b, float fog_near = -1.0f, float fog_far = -1.0f);
|
||||
void set_fill_mode(int mode);
|
||||
void set_cull_mode(int mode);
|
||||
void set_zbias(int bias);
|
||||
void set_center_alpha(int center_alpha);
|
||||
void set_lighting(bool mode);
|
||||
void set_buffer(int buffer);
|
||||
void set_team_color(const team_color &color);
|
||||
void set_team_color();
|
||||
void set_color(const color &clr);
|
||||
void set_animated_timer(float time);
|
||||
void set_animated_effect(int effect);
|
||||
void add_submodel_to_batch(int model_num);
|
||||
void start_model_batch(int n_models);
|
||||
|
||||
void add_buffer_draw(vertex_buffer *buffer, int texi, uint tmap_flags, model_render_params *interp);
|
||||
|
||||
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(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 set_light_factor(float factor);
|
||||
|
||||
void init_render();
|
||||
void render_all(int depth_mode = -1);
|
||||
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_immediate_render(int model_num, matrix *orient, vec3d * pos, uint flags = MR_NORMAL, int objnum = -1, int lighting_skip = -1, int *replacement_textures = NULL);
|
||||
void model_render_immediate(model_render_params *render_info, int model_num, matrix *orient, vec3d * pos, int render = MODEL_RENDER_ALL);
|
||||
void model_render_queue(model_render_params *render_info, draw_list* scene, int model_num, matrix *orient, vec3d *pos);
|
||||
//void model_queue_render(DrawList* scene, int model_num, int model_instance_num, matrix *orient, vec3d *pos, uint flags, int objnum, int *replacement_textures, const bool is_skybox = false);
|
||||
//void submodel_immediate_render(int model_num, int submodel_num, matrix *orient, vec3d * pos, uint flags = MR_NORMAL, int objnum = -1, int *replacement_textures = NULL);
|
||||
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 submodel_queue_render(model_render_params *interp, DrawList *scene, int model_num, int submodel_num, matrix *orient, vec3d * pos, uint flags, int objnum = -1);
|
||||
void model_render_buffers(draw_list* scene, 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);
|
||||
|
||||
#endif
|
||||
+97
-9
@@ -94,6 +94,8 @@ char *Object_type_names[MAX_OBJECT_TYPES] = {
|
||||
//XSTR:ON
|
||||
};
|
||||
|
||||
extern int Use_GLSL;
|
||||
|
||||
obj_flag_name Object_flag_names[] = {
|
||||
{OF_INVULNERABLE, "invulnerable", 1, },
|
||||
{OF_PROTECTED, "protect-ship", 1, },
|
||||
@@ -1202,7 +1204,8 @@ void obj_move_all_post(object *objp, float frametime)
|
||||
g = i2fl(c.green)/255.0f;
|
||||
b = i2fl(c.blue)/255.0f;
|
||||
|
||||
light_add_point( &objp->pos, 10.0f, 20.0f, 1.0f, r, g, b, objp->parent );
|
||||
//light_add_point( &objp->pos, 10.0f, 20.0f, 1.0f, r, g, b, objp->parent );
|
||||
light_add_point( &objp->pos, 10.0f, Use_GLSL>1?100.0f:20.0f, 1.0f, r, g, b, objp->parent );
|
||||
} else {
|
||||
light_add_point( &objp->pos, 10.0f, 20.0f, 1.0f, 1.0f, 1.0f, 1.0f, objp->parent );
|
||||
}
|
||||
@@ -1527,7 +1530,7 @@ MONITOR( NumObjectsRend )
|
||||
* Render an object. Calls one of several routines based on type
|
||||
*/
|
||||
extern int Cmdline_dis_weapons;
|
||||
void obj_render(object *obj)
|
||||
void obj_render_DEPRECATED(object *obj)
|
||||
{
|
||||
SCP_list<CJumpNode>::iterator jnp;
|
||||
|
||||
@@ -1548,22 +1551,22 @@ void obj_render(object *obj)
|
||||
break;
|
||||
case OBJ_WEAPON:
|
||||
if(Cmdline_dis_weapons) return;
|
||||
weapon_render(obj);
|
||||
weapon_render_DEPRECATED(obj);
|
||||
break;
|
||||
case OBJ_SHIP:
|
||||
ship_render(obj);
|
||||
ship_render_DEPRECATED(obj);
|
||||
break;
|
||||
case OBJ_FIREBALL:
|
||||
fireball_render(obj);
|
||||
fireball_render_DEPRECATED(obj);
|
||||
break;
|
||||
case OBJ_SHOCKWAVE:
|
||||
shockwave_render(obj);
|
||||
shockwave_render_DEPRECATED(obj);
|
||||
break;
|
||||
case OBJ_DEBRIS:
|
||||
debris_render(obj);
|
||||
debris_render_DEPRECATED(obj);
|
||||
break;
|
||||
case OBJ_ASTEROID:
|
||||
asteroid_render(obj);
|
||||
asteroid_render_DEPRECATED(obj);
|
||||
break;
|
||||
/* case OBJ_CMEASURE:
|
||||
cmeasure_render(obj);
|
||||
@@ -1572,7 +1575,7 @@ void obj_render(object *obj)
|
||||
for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
|
||||
if(jnp->GetSCPObject() != obj)
|
||||
continue;
|
||||
jnp->Render(&obj->pos, &Eye_position);
|
||||
jnp->RenderDEPRECATED(&obj->pos, &Eye_position);
|
||||
}
|
||||
break;
|
||||
case OBJ_WAYPOINT:
|
||||
@@ -1594,6 +1597,91 @@ void obj_render(object *obj)
|
||||
Script_system.RemHookVar("Self");
|
||||
}
|
||||
|
||||
void obj_render(object *obj)
|
||||
{
|
||||
draw_list render_list;
|
||||
|
||||
obj_queue_render(obj, &render_list);
|
||||
|
||||
render_list.init_render();
|
||||
render_list.render_all();
|
||||
|
||||
gr_zbias(0);
|
||||
gr_set_cull(0);
|
||||
gr_zbuffer_set(ZBUFFER_TYPE_READ);
|
||||
gr_set_fill_mode(GR_FILL_MODE_SOLID);
|
||||
|
||||
gr_clear_states();
|
||||
gr_set_buffer(-1);
|
||||
|
||||
gr_reset_lighting();
|
||||
gr_set_lighting(false, false);
|
||||
}
|
||||
|
||||
void obj_queue_render(object* obj, draw_list* scene)
|
||||
{
|
||||
if ( obj->flags & OF_SHOULD_BE_DEAD ) return;
|
||||
|
||||
// need to figure out what to do with this hook.
|
||||
// maybe save an array of these and run the script conditions after we finish drawing
|
||||
Script_system.SetHookObject("Self", obj);
|
||||
|
||||
if ( Script_system.IsConditionOverride(CHA_OBJECTRENDER, obj) ) {
|
||||
Script_system.RunCondition(CHA_OBJECTRENDER, '\0', NULL, obj);
|
||||
Script_system.RemHookVar("Self");
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( obj->type ) {
|
||||
case OBJ_NONE:
|
||||
#ifndef NDEBUG
|
||||
mprintf(( "ERROR!!!! Bogus obj %d is rendering!\n", obj-Objects ));
|
||||
Int3();
|
||||
#endif
|
||||
break;
|
||||
case OBJ_WEAPON:
|
||||
if ( Cmdline_dis_weapons ) return;
|
||||
weapon_render(obj, scene);
|
||||
break;
|
||||
case OBJ_SHIP:
|
||||
ship_render(obj, scene);
|
||||
break;
|
||||
case OBJ_FIREBALL:
|
||||
fireball_render(obj, scene);
|
||||
break;
|
||||
case OBJ_SHOCKWAVE:
|
||||
shockwave_render(obj, scene);
|
||||
break;
|
||||
case OBJ_DEBRIS:
|
||||
debris_render(obj, scene);
|
||||
break;
|
||||
case OBJ_ASTEROID:
|
||||
asteroid_render(obj, scene);
|
||||
break;
|
||||
case OBJ_JUMP_NODE:
|
||||
for ( SCP_list<CJumpNode>::iterator jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp ) {
|
||||
if ( jnp->GetSCPObject() != obj ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
jnp->Render(scene, &obj->pos, &Eye_position);
|
||||
}
|
||||
break;
|
||||
case OBJ_WAYPOINT:
|
||||
// if (Show_waypoints) {
|
||||
// gr_set_color( 128, 128, 128 );
|
||||
// g3_draw_sphere_ez( &obj->pos, 5.0f );
|
||||
// }
|
||||
break;
|
||||
case OBJ_GHOST:
|
||||
break;
|
||||
case OBJ_BEAM:
|
||||
break;
|
||||
default:
|
||||
Error( LOCATION, "Unhandled obj type %d in obj_render", obj->type );
|
||||
}
|
||||
}
|
||||
|
||||
void obj_init_all_ships_physics()
|
||||
{
|
||||
object *objp;
|
||||
|
||||
@@ -136,6 +136,7 @@ typedef struct obj_flag_name {
|
||||
extern obj_flag_name Object_flag_names[];
|
||||
|
||||
struct dock_instance;
|
||||
class draw_list;
|
||||
|
||||
class object
|
||||
{
|
||||
@@ -248,7 +249,11 @@ void obj_init();
|
||||
int obj_create(ubyte type,int parent_obj, int instance, matrix * orient, vec3d * pos, float radius, uint flags );
|
||||
|
||||
//Render an object. Calls one of several routines based on type
|
||||
void obj_render(object *obj);
|
||||
void obj_render_DEPRECATED(object *obj);
|
||||
|
||||
void obj_render(object* obj);
|
||||
|
||||
void obj_queue_render(object* obj, draw_list* scene);
|
||||
|
||||
//Sorts and renders all the ojbects
|
||||
void obj_render_all(void (*render_function)(object *objp), bool* render_viewer_last );
|
||||
@@ -342,4 +347,6 @@ bool object_glide_forced(object* objp);
|
||||
int obj_get_by_signature(int sig);
|
||||
int object_get_model(object *objp);
|
||||
|
||||
void obj_render_queue_all();
|
||||
|
||||
#endif
|
||||
+122
-6
@@ -15,13 +15,17 @@
|
||||
#include "mission/missionparse.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "jumpnode/jumpnode.h"
|
||||
#include "weapon/weapon.h"
|
||||
#include "debris/debris.h"
|
||||
#include "asteroid/asteroid.h"
|
||||
|
||||
#include "model/modelrender.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "graphics/gropengldraw.h"
|
||||
#include "parse/scripting.h"
|
||||
|
||||
class sorted_obj
|
||||
{
|
||||
@@ -104,7 +108,8 @@ inline bool sorted_obj::operator < (const sorted_obj &other) const
|
||||
|
||||
SCP_vector<sorted_obj> Sorted_objects;
|
||||
SCP_vector<object*> effect_ships;
|
||||
|
||||
SCP_vector<object*> transparent_objects;
|
||||
bool object_had_transparency = false;
|
||||
// Used to (fairly) quicky find the 8 extreme
|
||||
// points around an object.
|
||||
vec3d check_offsets[8] = {
|
||||
@@ -281,17 +286,22 @@ void obj_render_all(void (*render_function)(object *objp), bool *draw_viewer_las
|
||||
}
|
||||
|
||||
if ( obj_render_is_model(obj) ) {
|
||||
if( (obj->type == OBJ_SHIP) && Ships[obj->instance].shader_effect_active )
|
||||
if( (obj->type == OBJ_SHIP) && Ships[obj->instance].shader_effect_active || obj->type == OBJ_FIREBALL )
|
||||
effect_ships.push_back(obj);
|
||||
else
|
||||
(*render_function)(obj);
|
||||
}
|
||||
if(object_had_transparency)
|
||||
{
|
||||
object_had_transparency = false;
|
||||
transparent_objects.push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
gr_deferred_lighting_end();
|
||||
Interp_no_flush = 0;
|
||||
|
||||
// we're done rendering models so flush render states
|
||||
gr_flush_data_states();
|
||||
gr_clear_states();
|
||||
gr_set_buffer(-1);
|
||||
|
||||
// render everything else that isn't a model
|
||||
@@ -337,3 +347,109 @@ void obj_render_all(void (*render_function)(object *objp), bool *draw_viewer_las
|
||||
batch_render_all();
|
||||
}
|
||||
|
||||
void obj_render_queue_all()
|
||||
{
|
||||
object *objp;
|
||||
int i;
|
||||
draw_list scene;
|
||||
|
||||
objp = Objects;
|
||||
|
||||
gr_deferred_lighting_begin();
|
||||
|
||||
scene.init();
|
||||
|
||||
for ( i = 0; i <= Highest_object_index; i++,objp++ ) {
|
||||
if ( (objp->type != OBJ_NONE) && ( objp->flags & OF_RENDERS ) ) {
|
||||
objp->flags &= ~OF_WAS_RENDERED;
|
||||
|
||||
if ( !obj_in_view_cone(objp) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (The_mission.flags & MISSION_FLAG_FULLNEB) && (Neb2_render_mode != NEB2_RENDER_NONE) && !Fred_running ) {
|
||||
vec3d to_obj;
|
||||
vm_vec_sub( &to_obj, &objp->pos, &Eye_position );
|
||||
float z = vm_vec_dot( &Eye_matrix.vec.fvec, &to_obj );
|
||||
|
||||
if ( neb2_skip_render(objp, z) ){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( obj_render_is_model(objp) ) {
|
||||
if( (objp->type == OBJ_SHIP) && Ships[objp->instance].shader_effect_active ) {
|
||||
effect_ships.push_back(objp);
|
||||
}
|
||||
}
|
||||
|
||||
objp->flags |= OF_WAS_RENDERED;
|
||||
profile_begin("Queue Render");
|
||||
obj_queue_render(objp, &scene);
|
||||
profile_end("Queue Render");
|
||||
}
|
||||
}
|
||||
|
||||
scene.init_render();
|
||||
|
||||
PROFILE("Submit Draws", scene.render_all(GR_ZBUFF_FULL));
|
||||
gr_zbuffer_set(ZBUFFER_TYPE_READ);
|
||||
gr_zbias(0);
|
||||
gr_set_cull(0);
|
||||
|
||||
gr_clear_states();
|
||||
gr_set_buffer(-1);
|
||||
gr_set_fill_mode(GR_FILL_MODE_SOLID);
|
||||
|
||||
gr_deferred_lighting_end();
|
||||
PROFILE("Apply Lights", gr_deferred_lighting_finish());
|
||||
|
||||
gr_zbuffer_set(ZBUFFER_TYPE_READ);
|
||||
|
||||
gr_reset_lighting();
|
||||
gr_set_lighting(false, false);
|
||||
|
||||
// now render transparent meshes
|
||||
PROFILE("Submit Draws", scene.render_all(GR_ZBUFF_READ));
|
||||
PROFILE("Submit Draws", scene.render_all(GR_ZBUFF_NONE));
|
||||
|
||||
// render electricity effects and insignias
|
||||
scene.render_outlines();
|
||||
scene.render_insignias();
|
||||
scene.render_arcs();
|
||||
|
||||
gr_zbuffer_set(ZBUFFER_TYPE_READ);
|
||||
gr_zbias(0);
|
||||
gr_set_cull(0);
|
||||
gr_set_fill_mode(GR_FILL_MODE_SOLID);
|
||||
|
||||
gr_clear_states();
|
||||
gr_set_buffer(-1);
|
||||
|
||||
gr_reset_lighting();
|
||||
gr_set_lighting(false, false);
|
||||
|
||||
//WMC - draw maneuvering thrusters
|
||||
extern void batch_render_man_thrusters();
|
||||
batch_render_man_thrusters();
|
||||
|
||||
// if we're fullneb, switch off the fog effet
|
||||
if((The_mission.flags & MISSION_FLAG_FULLNEB) && (Neb2_render_mode != NEB2_RENDER_NONE)){
|
||||
gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
|
||||
}
|
||||
|
||||
PROFILE("Draw Effects", batch_render_all());
|
||||
|
||||
gr_zbias(0);
|
||||
gr_zbuffer_set(ZBUFFER_TYPE_READ);
|
||||
gr_set_cull(0);
|
||||
gr_set_fill_mode(GR_FILL_MODE_SOLID);
|
||||
|
||||
gr_clear_states();
|
||||
gr_set_buffer(-1);
|
||||
|
||||
gr_reset_lighting();
|
||||
gr_set_lighting(false, false);
|
||||
|
||||
GL_state.Texture.DisableAll();
|
||||
}
|
||||
+24
-12
@@ -6040,9 +6040,10 @@ ADE_FUNC(renderTechModel, l_Shipclass, "X1, Y1, X2, Y2, [Rotation %=0, Pitch %=0
|
||||
CLAMP(rot_angles.h, 0.0f, 100.0f);
|
||||
|
||||
ship_info *sip = &Ship_info[idx];
|
||||
model_render_params render_info;
|
||||
|
||||
if (sip->uses_team_colors) {
|
||||
gr_set_team_color(sip->default_team_name, "none", 0, 0);
|
||||
render_info.set_team_color(sip->default_team_name, "none", 0, 0);
|
||||
}
|
||||
|
||||
//Make sure model is loaded
|
||||
@@ -6080,14 +6081,16 @@ ADE_FUNC(renderTechModel, l_Shipclass, "X1, Y1, X2, Y2, [Rotation %=0, Pitch %=0
|
||||
|
||||
//Draw the ship!!
|
||||
model_clear_instance(sip->model_num);
|
||||
model_set_detail_level(0);
|
||||
render_info.set_detail_level_lock(0);
|
||||
|
||||
uint render_flags = MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING;
|
||||
uint render_flags = MR_AUTOCENTER | MR_NO_FOGGING;
|
||||
|
||||
if(sip->flags2 & SIF2_NO_LIGHTING)
|
||||
render_flags |= MR_NO_LIGHTING;
|
||||
|
||||
model_render(sip->model_num, &orient, &vmd_zero_vector, render_flags);
|
||||
render_info.set_flags(render_flags);
|
||||
|
||||
model_render_immediate(&render_info, sip->model_num, &orient, &vmd_zero_vector);
|
||||
|
||||
//OK we're done
|
||||
gr_end_view_matrix();
|
||||
@@ -6096,7 +6099,6 @@ ADE_FUNC(renderTechModel, l_Shipclass, "X1, Y1, X2, Y2, [Rotation %=0, Pitch %=0
|
||||
//Bye!!
|
||||
g3_end_frame();
|
||||
gr_reset_clip();
|
||||
gr_disable_team_color();
|
||||
|
||||
return ade_set_args(L, "b", true);
|
||||
}
|
||||
@@ -6118,9 +6120,10 @@ ADE_FUNC(renderTechModel2, l_Shipclass, "X1, Y1, X2, Y2, [orientation Orientatio
|
||||
return ade_set_args(L, "b", false);
|
||||
|
||||
ship_info *sip = &Ship_info[idx];
|
||||
model_render_params render_info;
|
||||
|
||||
if (sip->uses_team_colors) {
|
||||
gr_set_team_color(sip->default_team_name, "none", 0, 0);
|
||||
render_info.set_team_color(sip->default_team_name, "none", 0, 0);
|
||||
}
|
||||
|
||||
//Make sure model is loaded
|
||||
@@ -6151,14 +6154,16 @@ ADE_FUNC(renderTechModel2, l_Shipclass, "X1, Y1, X2, Y2, [orientation Orientatio
|
||||
|
||||
//Draw the ship!!
|
||||
model_clear_instance(sip->model_num);
|
||||
model_set_detail_level(0);
|
||||
render_info.set_detail_level_lock(0);
|
||||
|
||||
uint render_flags = MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_FOGGING;
|
||||
uint render_flags = MR_AUTOCENTER | MR_NO_FOGGING;
|
||||
|
||||
if(sip->flags2 & SIF2_NO_LIGHTING)
|
||||
render_flags |= MR_NO_LIGHTING;
|
||||
|
||||
model_render(sip->model_num, orient, &vmd_zero_vector, render_flags);
|
||||
render_info.set_flags(render_flags);
|
||||
|
||||
model_render_immediate(&render_info, sip->model_num, orient, &vmd_zero_vector);
|
||||
|
||||
//OK we're done
|
||||
gr_end_view_matrix();
|
||||
@@ -6167,7 +6172,6 @@ ADE_FUNC(renderTechModel2, l_Shipclass, "X1, Y1, X2, Y2, [orientation Orientatio
|
||||
//Bye!!
|
||||
g3_end_frame();
|
||||
gr_reset_clip();
|
||||
gr_disable_team_color();
|
||||
|
||||
return ade_set_args(L, "b", true);
|
||||
}
|
||||
@@ -13497,7 +13501,11 @@ ADE_FUNC(drawModel, l_Graphics, "model, position, orientation", "Draws the given
|
||||
//Draw the ship!!
|
||||
model_clear_instance(model_num);
|
||||
model_set_detail_level(0);
|
||||
model_render(model_num, orient, v, MR_NORMAL);
|
||||
model_render_params render_info;
|
||||
|
||||
render_info.set_detail_level_lock(0);
|
||||
|
||||
model_render_immediate(&render_info, model_num, orient, v);
|
||||
|
||||
//OK we're done
|
||||
gr_end_view_matrix();
|
||||
@@ -13538,7 +13546,11 @@ ADE_FUNC(drawModelOOR, l_Graphics, "model Model, vector Position, matrix Orienta
|
||||
|
||||
//Draw the ship!!
|
||||
model_clear_instance(model_num);
|
||||
model_render(model_num, orient, v, flags);
|
||||
|
||||
model_render_params render_info;
|
||||
render_info.set_flags(flags);
|
||||
|
||||
model_render_immediate(&render_info, model_num, orient, v);
|
||||
|
||||
return ade_set_args(L, "i", 0);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "graphics/grbatch.h"
|
||||
#include "debugconsole/console.h"
|
||||
#include "graphics/gropenglextension.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#include "io/timer.h"
|
||||
@@ -40,6 +41,7 @@ static int Particles_enabled = 1;
|
||||
uint lastSignature = 0; // 0 is an invalid signature!
|
||||
|
||||
int Particle_buffer_object = -1;
|
||||
int Geometry_shader_buffer_object = -1;
|
||||
|
||||
// Reset everything between levels
|
||||
void particle_init()
|
||||
@@ -71,6 +73,10 @@ void particle_init()
|
||||
if ( Particle_buffer_object < 0 ) {
|
||||
Particle_buffer_object = gr_create_stream_buffer();
|
||||
}
|
||||
|
||||
if ( Geometry_shader_buffer_object < 0 && !Cmdline_no_geo_sdr_effects && Is_Extension_Enabled(OGL_EXT_GEOMETRY_SHADER4) ) {
|
||||
Geometry_shader_buffer_object = gr_create_stream_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
// only call from game_shutdown()!!!
|
||||
@@ -434,7 +440,7 @@ void particle_render_all()
|
||||
}
|
||||
// draw as a regular bitmap
|
||||
else {
|
||||
batch_add_bitmap( framenum + cur_frame, tmap_flags, &pos, part->particle_index % 8, part->radius, alpha );
|
||||
batch_add_bitmap( framenum + cur_frame, tmap_flags | TMAP_FLAG_VERTEX_GEN, &pos, part->particle_index % 8, part->radius, alpha );
|
||||
}
|
||||
|
||||
render_batch = true;
|
||||
@@ -443,6 +449,7 @@ void particle_render_all()
|
||||
|
||||
profile_begin("Batch Render");
|
||||
if (render_batch) {
|
||||
geometry_batch_render(Geometry_shader_buffer_object);
|
||||
batch_render_all(Particle_buffer_object);
|
||||
}
|
||||
profile_end("Batch Render");
|
||||
@@ -536,5 +543,4 @@ void particle_emit( particle_emitter *pe, int type, int optional_data, float ran
|
||||
|
||||
particle_create( &pe->pos, &tmp_vel, life, radius, type, optional_data );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -397,5 +397,6 @@ public:
|
||||
void initialize(int number, float min_ray_width, float max_ray_width = 0, vec3d* dir = &vmd_zero_vector, vec3d*pcenter = &vmd_zero_vector, float outer = PI2, float inner = 0.0f, ubyte max_r = 255, ubyte max_g = 255, ubyte max_b = 255, ubyte min_r = 255, ubyte min_g = 255, ubyte min_b = 255);
|
||||
void initialize(ubyte *bsp_data, float min_ray_width, float max_ray_width = 0, vec3d* dir = &vmd_zero_vector, vec3d*pcenter = &vmd_zero_vector, float outer = PI2, float inner = 0.0f, ubyte max_r = 255, ubyte max_g = 255, ubyte max_b = 255, ubyte min_r = 255, ubyte min_g = 255, ubyte min_b = 255);
|
||||
void render(float rad, float intinsity, float life);
|
||||
void render(int texture, float rad, float intinsity, float life);
|
||||
};
|
||||
#endif
|
||||
@@ -2196,4 +2196,16 @@ void flash_ball::render(float rad, float intinsity, float life){
|
||||
flash_ball::batcher.render(TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);
|
||||
}
|
||||
|
||||
void flash_ball::render(int texture, float rad, float intinsity, float life){
|
||||
flash_ball::batcher.allocate(n_rays);
|
||||
for(int i = 0; i<n_rays; i++){
|
||||
vec3d end;
|
||||
vm_vec_interp_constant(&end, &ray[i].start.world, &ray[i].end.world, life);
|
||||
vm_vec_scale(&end, rad);
|
||||
vm_vec_add2(&end, ¢er);
|
||||
|
||||
batch_add_beam(texture, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT, ¢er, &end, ray[i].width*rad, intinsity);
|
||||
}
|
||||
}
|
||||
|
||||
geometry_batcher flash_ball::batcher;
|
||||
@@ -288,7 +288,7 @@ void g3_start_instance_matrix(vec3d *pos,matrix *orient, bool set_api)
|
||||
vm_matrix_x_matrix(&tempm,&tempm2,&View_matrix);
|
||||
View_matrix = tempm;
|
||||
|
||||
vm_matrix_x_matrix(&Object_matrix,orient,&instance_stack[instance_depth-1].om);
|
||||
vm_matrix_x_matrix(&Object_matrix,&instance_stack[instance_depth-1].om,orient);
|
||||
|
||||
// Update the lighting matrix
|
||||
matrix saved_orient = Light_matrix;
|
||||
@@ -393,12 +393,12 @@ void g3_start_user_clip_plane( vec3d *plane_point, vec3d *plane_normal )
|
||||
G3_user_clip_point = *plane_point;
|
||||
gr_start_clip();
|
||||
}
|
||||
vm_vec_rotate(&G3_user_clip_normal, plane_normal, &View_matrix );
|
||||
vm_vec_rotate(&G3_user_clip_normal, plane_normal, &Eye_matrix );
|
||||
vm_vec_normalize(&G3_user_clip_normal);
|
||||
|
||||
vec3d tempv;
|
||||
vm_vec_sub(&tempv,plane_point,&View_position);
|
||||
vm_vec_rotate(&G3_user_clip_point,&tempv,&View_matrix );
|
||||
vm_vec_sub(&tempv,plane_point,&Eye_position);
|
||||
vm_vec_rotate(&G3_user_clip_point,&tempv,&Eye_matrix );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -426,4 +426,4 @@ int g3_point_behind_user_plane( vec3d *pnt )
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+749
-191
File diff suppressed because it is too large.
Load diff
+4
-1
@@ -1434,6 +1434,8 @@ public:
|
||||
SCP_vector<cockpit_display_info> displays;
|
||||
|
||||
SCP_map<SCP_string, path_metadata> pathMetadata;
|
||||
|
||||
SCP_hash_map<int, void*> glowpoint_bank_override_map;
|
||||
};
|
||||
|
||||
extern int Num_wings;
|
||||
@@ -1577,7 +1579,8 @@ extern void change_ship_type(int n, int ship_type, int by_sexp = 0);
|
||||
extern void ship_model_change(int n, int ship_type);
|
||||
extern void ship_process_pre( object * objp, float frametime );
|
||||
extern void ship_process_post( object * objp, float frametime );
|
||||
extern void ship_render( object * objp );
|
||||
extern void ship_render_DEPRECATED( object * objp );
|
||||
extern void ship_render( object * obj, draw_list * scene );
|
||||
extern void ship_render_cockpit( object * objp);
|
||||
extern void ship_render_show_ship_cockpit( object * objp);
|
||||
extern void ship_delete( object * objp );
|
||||
|
||||
@@ -137,6 +137,9 @@ void ct_ship_process(ship *shipp)
|
||||
shipp->trail_ptr[idx] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// don't create or update trails if we're not moving fast enough
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+176
-7
@@ -40,9 +40,9 @@
|
||||
#include "bmpman/bmpman.h"
|
||||
#include "model/model.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "model/modelrender.h"
|
||||
#include "debugconsole/console.h"
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
extern float flFrametime;
|
||||
extern int Framecount;
|
||||
@@ -1828,7 +1828,7 @@ static void half_ship_render_ship_and_debris(clip_ship* half_ship,ship *shipp)
|
||||
g3_start_user_clip_plane( &debris_clip_plane_pt, &clip_plane_norm);
|
||||
|
||||
// set up render flags
|
||||
uint render_flags = MR_NORMAL;
|
||||
uint render_flags = MR_DEPRECATED_NORMAL;
|
||||
|
||||
for (int i=0; i<pm->num_debris_objects; i++ ) {
|
||||
// draw DEBRIS_FREE in test only
|
||||
@@ -1856,7 +1856,7 @@ static void half_ship_render_ship_and_debris(clip_ship* half_ship,ship *shipp)
|
||||
// Draw debris, but not live debris
|
||||
if ( !is_live_debris ) {
|
||||
model_find_world_point(&tmp, &tmp1, pm->id, -1, &half_ship->orient, &temp_pos);
|
||||
submodel_render(pm->id, pm->debris_objects[i], &half_ship->orient, &tmp, render_flags, -1, shipp->ship_replacement_textures);
|
||||
submodel_render_DEPRECATED(pm->id, pm->debris_objects[i], &half_ship->orient, &tmp, render_flags, -1, shipp->ship_replacement_textures);
|
||||
}
|
||||
|
||||
// make free piece of debris
|
||||
@@ -1900,7 +1900,113 @@ static void half_ship_render_ship_and_debris(clip_ship* half_ship,ship *shipp)
|
||||
vm_vec_unrotate(&model_clip_plane_pt, &temp, &half_ship->orient);
|
||||
vm_vec_add2(&model_clip_plane_pt, &orig_ship_world_center);
|
||||
g3_start_user_clip_plane( &model_clip_plane_pt, &clip_plane_norm );
|
||||
model_render(pm->id, &half_ship->orient, &orig_ship_world_center, render_flags, -1, -1, shipp->ship_replacement_textures);
|
||||
model_render_DEPRECATED(pm->id, &half_ship->orient, &orig_ship_world_center, render_flags, -1, -1, shipp->ship_replacement_textures);
|
||||
}
|
||||
|
||||
void shipfx_queue_render_ship_halves_and_debris(draw_list *scene, clip_ship* half_ship, ship *shipp)
|
||||
{
|
||||
polymodel *pm = model_get(Ship_info[shipp->ship_info_index].model_num);
|
||||
|
||||
// get rotated clip plane normal and world coord of original ship center
|
||||
vec3d orig_ship_world_center, clip_plane_norm, model_clip_plane_pt, debris_clip_plane_pt;
|
||||
vm_vec_unrotate(&clip_plane_norm, &half_ship->clip_plane_norm, &half_ship->orient);
|
||||
vm_vec_unrotate(&orig_ship_world_center, &half_ship->model_center_disp_to_orig_center, &half_ship->orient);
|
||||
vm_vec_add2(&orig_ship_world_center, &half_ship->local_pivot);
|
||||
|
||||
// get debris clip plane pt and draw debris
|
||||
vm_vec_unrotate(&debris_clip_plane_pt, &half_ship->model_center_disp_to_orig_center, &half_ship->orient);
|
||||
vm_vec_add2(&debris_clip_plane_pt, &half_ship->local_pivot);
|
||||
|
||||
// set up render flags
|
||||
uint render_flags = MR_NORMAL;
|
||||
|
||||
if ( Rendering_to_shadow_map ) {
|
||||
render_flags |= MR_NO_TEXTURING | MR_NO_LIGHTING;
|
||||
}
|
||||
|
||||
for (int i = 0; i < pm->num_debris_objects; i++ ) {
|
||||
// draw DEBRIS_FREE in test only
|
||||
if (half_ship->draw_debris[i] == DEBRIS_DRAW) {
|
||||
vec3d temp_pos = orig_ship_world_center;
|
||||
vec3d tmp = ZERO_VECTOR;
|
||||
vec3d tmp1 = pm->submodel[pm->debris_objects[i]].offset;
|
||||
|
||||
// determine if explosion front has past debris piece
|
||||
// 67 ~ dist expl moves in 2 frames -- maybe fraction works better
|
||||
int is_live_debris = pm->submodel[pm->debris_objects[i]].is_live_debris;
|
||||
int create_debris = 0;
|
||||
// front ship
|
||||
if (half_ship->explosion_vel > 0) {
|
||||
if (half_ship->cur_clip_plane_pt > tmp1.xyz.z + pm->submodel[pm->debris_objects[i]].max.xyz.z - 0.1f*half_ship->explosion_vel) {
|
||||
create_debris = 1;
|
||||
}
|
||||
// back ship
|
||||
} else {
|
||||
if (half_ship->cur_clip_plane_pt < tmp1.xyz.z + pm->submodel[pm->debris_objects[i]].min.xyz.z - 0.1f*half_ship->explosion_vel) {
|
||||
create_debris = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw debris, but not live debris
|
||||
if ( !is_live_debris ) {
|
||||
model_find_world_point(&tmp, &tmp1, pm->id, -1, &half_ship->orient, &temp_pos);
|
||||
model_render_params render_info;
|
||||
|
||||
render_info.set_clip_plane(debris_clip_plane_pt, clip_plane_norm);
|
||||
render_info.set_replacement_textures(shipp->ship_replacement_textures);
|
||||
render_info.set_flags(render_flags);
|
||||
|
||||
submodel_render_queue(&render_info, scene, pm->id, pm->debris_objects[i], &half_ship->orient, &tmp);
|
||||
}
|
||||
|
||||
// make free piece of debris
|
||||
if ( create_debris ) {
|
||||
half_ship->draw_debris[i] = DEBRIS_FREE; // mark debris to not render with model
|
||||
vec3d center_to_debris, debris_vel, radial_vel;
|
||||
// check if last debris piece, ie, debris_count == 0
|
||||
int debris_count = 0;
|
||||
for (int j=0; j<pm->num_debris_objects; j++ ) {
|
||||
if (half_ship->draw_debris[j] == DEBRIS_DRAW) {
|
||||
debris_count++;
|
||||
}
|
||||
}
|
||||
// do debris create here, but not for live debris
|
||||
// debris vel (1) split ship vel (2) split ship rotvel (3) random
|
||||
if ( !is_live_debris ) {
|
||||
object* debris_obj;
|
||||
debris_obj = debris_create(half_ship->parent_obj, pm->id, pm->debris_objects[i], &tmp, &half_ship->local_pivot, 1, 1.0f);
|
||||
// AL: make sure debris_obj isn't NULL!
|
||||
if ( debris_obj ) {
|
||||
vm_vec_scale(&debris_obj->phys_info.rotvel, 4.0f);
|
||||
debris_obj->orient = half_ship->orient;
|
||||
|
||||
vm_vec_sub(¢er_to_debris, &tmp, &half_ship->local_pivot);
|
||||
vm_vec_crossprod(&debris_vel, ¢er_to_debris, &half_ship->phys_info.rotvel);
|
||||
vm_vec_add2(&debris_vel, &half_ship->phys_info.vel);
|
||||
vm_vec_copy_normalize(&radial_vel, ¢er_to_debris);
|
||||
float radial_mag = 10.0f + 30.0f*frand();
|
||||
vm_vec_scale_add2(&debris_vel, &radial_vel, radial_mag);
|
||||
debris_obj->phys_info.vel = debris_vel;
|
||||
shipfx_debris_limit_speed(&Debris[debris_obj->instance], shipp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get model clip plane pt and draw model
|
||||
vec3d temp;
|
||||
vm_vec_make(&temp, 0.0f, 0.0f, half_ship->cur_clip_plane_pt);
|
||||
vm_vec_unrotate(&model_clip_plane_pt, &temp, &half_ship->orient);
|
||||
vm_vec_add2(&model_clip_plane_pt, &orig_ship_world_center);
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
render_info.set_flags(render_flags);
|
||||
render_info.set_clip_plane(model_clip_plane_pt, clip_plane_norm);
|
||||
render_info.set_replacement_textures(shipp->ship_replacement_textures);
|
||||
|
||||
model_render_queue(&render_info, scene, pm->id, &half_ship->orient, &orig_ship_world_center);
|
||||
}
|
||||
|
||||
void shipfx_large_blowup_level_init()
|
||||
@@ -2287,6 +2393,22 @@ void shipfx_large_blowup_render(ship* shipp)
|
||||
g3_stop_user_clip_plane();
|
||||
}
|
||||
|
||||
void shipfx_large_blowup_queue_render(draw_list *scene, ship* shipp)
|
||||
{
|
||||
Assert( shipp->large_ship_blowup_index > -1 );
|
||||
Assert( shipp->large_ship_blowup_index < (int)Split_ships.size() );
|
||||
|
||||
split_ship *the_split_ship = &Split_ships[shipp->large_ship_blowup_index];
|
||||
Assert( the_split_ship->used ); // Get John
|
||||
|
||||
if (the_split_ship->front_ship.length_left > 0) {
|
||||
shipfx_queue_render_ship_halves_and_debris(scene, &the_split_ship->front_ship,shipp);
|
||||
}
|
||||
|
||||
if (the_split_ship->back_ship.length_left > 0) {
|
||||
shipfx_queue_render_ship_halves_and_debris(scene, &the_split_ship->back_ship,shipp);
|
||||
}
|
||||
}
|
||||
|
||||
// ================== DO THE ELECTRIC ARCING STUFF =====================
|
||||
// Creates any new ones, moves old ones.
|
||||
@@ -3369,11 +3491,21 @@ int WarpEffect::warpShipClip()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WarpEffect::warpShipClip(model_render_params *render_info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WarpEffect::warpShipRender()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WarpEffect::warpShipQueueRender(draw_list *scene)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WarpEffect::warpEnd()
|
||||
{
|
||||
if(!this->isValid())
|
||||
@@ -3648,6 +3780,16 @@ int WE_Default::warpShipClip()
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WE_Default::warpShipClip(model_render_params *render_info)
|
||||
{
|
||||
if(!this->isValid())
|
||||
return 0;
|
||||
|
||||
render_info->set_clip_plane(pos, fvec);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WE_Default::warpShipRender()
|
||||
{
|
||||
return 1;
|
||||
@@ -3931,6 +4073,22 @@ int WE_BSG::warpShipClip()
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WE_BSG::warpShipClip(model_render_params *render_info)
|
||||
{
|
||||
if(!this->isValid())
|
||||
return 0;
|
||||
|
||||
if(direction == WD_WARP_OUT && stage > 0)
|
||||
{
|
||||
vec3d position;
|
||||
vm_vec_scale_add(&position, &objp->pos, &objp->orient.vec.fvec, objp->radius);
|
||||
|
||||
render_info->set_clip_plane(position, objp->orient.vec.fvec);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WE_BSG::warpShipRender()
|
||||
{
|
||||
if(!this->isValid())
|
||||
@@ -3953,7 +4111,7 @@ int WE_BSG::warpShipRender()
|
||||
if ( anim_frame < anim_nframes )
|
||||
{
|
||||
//Set the correct frame
|
||||
gr_set_bitmap(anim + anim_frame, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
|
||||
//gr_set_bitmap(anim + anim_frame, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
|
||||
|
||||
//Do warpout geometry
|
||||
vec3d start, end;
|
||||
@@ -4239,6 +4397,15 @@ int WE_Homeworld::warpShipClip()
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WE_Homeworld::warpShipClip(model_render_params *render_info)
|
||||
{
|
||||
if(!this->isValid())
|
||||
return 0;
|
||||
|
||||
render_info->set_clip_plane(pos, fvec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WE_Homeworld::warpShipRender()
|
||||
{
|
||||
if(!this->isValid())
|
||||
@@ -4249,8 +4416,10 @@ int WE_Homeworld::warpShipRender()
|
||||
frame = fl2i( (int)(((float)(timestamp() - (float)total_time_start)/1000.0f) * (float)anim_fps) % anim_nframes);
|
||||
|
||||
//Set the correct frame
|
||||
gr_set_bitmap(anim + frame, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
|
||||
g3_draw_polygon(&pos, &objp->orient, width, height, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
|
||||
// gr_set_bitmap(anim + frame, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
|
||||
// g3_draw_polygon(&pos, &objp->orient, width, height, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT);
|
||||
batch_add_polygon(anim + frame, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT, &pos, &objp->orient, width, height);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "graphics/grbatch.h"
|
||||
#include "model/modelrender.h"
|
||||
|
||||
class object;
|
||||
class ship;
|
||||
@@ -112,6 +113,8 @@ int shipfx_large_blowup_do_frame(ship *shipp, float frametime);
|
||||
|
||||
void shipfx_large_blowup_render(ship *shipp);
|
||||
|
||||
void shipfx_large_blowup_queue_render(draw_list *scene, ship* shipp);
|
||||
|
||||
void shipfx_debris_limit_speed(struct debris *db, ship *shipp);
|
||||
|
||||
// sound manager fore big ship sub explosions sounds
|
||||
@@ -179,7 +182,9 @@ public:
|
||||
virtual int warpStart();
|
||||
virtual int warpFrame(float frametime);
|
||||
virtual int warpShipClip();
|
||||
virtual int warpShipClip(model_render_params *render_info);
|
||||
virtual int warpShipRender();
|
||||
virtual int warpShipQueueRender(draw_list *scene);
|
||||
virtual int warpEnd();
|
||||
|
||||
//For VM_WARP_CHASE
|
||||
@@ -216,6 +221,7 @@ public:
|
||||
int warpStart();
|
||||
int warpFrame(float frametime);
|
||||
int warpShipClip();
|
||||
int warpShipClip(model_render_params *render_info);
|
||||
int warpShipRender();
|
||||
|
||||
int getWarpPosition(vec3d *output);
|
||||
@@ -273,6 +279,7 @@ public:
|
||||
virtual int warpStart();
|
||||
virtual int warpFrame(float frametime);
|
||||
virtual int warpShipClip();
|
||||
virtual int warpShipClip(model_render_params *render_info);
|
||||
virtual int warpShipRender();
|
||||
virtual int warpEnd();
|
||||
|
||||
@@ -322,6 +329,7 @@ public:
|
||||
virtual int warpStart();
|
||||
virtual int warpFrame(float frametime);
|
||||
virtual int warpShipClip();
|
||||
virtual int warpShipClip(model_render_params *render_info);
|
||||
virtual int warpShipRender();
|
||||
virtual int warpEnd();
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
#include "parse/parselo.h"
|
||||
#include "hud/hud.h"
|
||||
#include "hud/hudtarget.h"
|
||||
#include "model/modelrender.h"
|
||||
#include "debugconsole/console.h"
|
||||
|
||||
|
||||
#define MAX_DEBRIS_VCLIPS 4
|
||||
#define DEBRIS_ROT_MIN 10000
|
||||
#define DEBRIS_ROT_RANGE 8
|
||||
@@ -1431,12 +1431,14 @@ void subspace_render()
|
||||
Interp_subspace_offset_u = 1.0f - subspace_offset_u;
|
||||
Interp_subspace_offset_v = 0.0f;
|
||||
|
||||
model_set_alpha(1.0f);
|
||||
model_render_params render_info;
|
||||
render_info.set_alpha(1.0f);
|
||||
render_info.set_flags(render_flags);
|
||||
|
||||
if (!Cmdline_nohtl)
|
||||
gr_set_texture_panning(Interp_subspace_offset_v, Interp_subspace_offset_u, true);
|
||||
|
||||
model_render( Subspace_model_outer, &tmp, &Eye_position, render_flags ); //MR_NO_CORRECT|MR_SHOW_OUTLINE
|
||||
model_render_immediate( &render_info, Subspace_model_outer, &tmp, &Eye_position); //MR_NO_CORRECT|MR_SHOW_OUTLINE
|
||||
|
||||
if (!Cmdline_nohtl)
|
||||
gr_set_texture_panning(0, 0, false);
|
||||
@@ -1449,14 +1451,14 @@ void subspace_render()
|
||||
|
||||
vm_angles_2_matrix(&tmp,&angs);
|
||||
|
||||
model_set_outline_color(255,255,255);
|
||||
|
||||
model_set_alpha(1.0f);
|
||||
render_info.set_outline_color(255, 255, 255);
|
||||
render_info.set_alpha(1.0f);
|
||||
render_info.set_flags(render_flags);
|
||||
|
||||
if (!Cmdline_nohtl)
|
||||
gr_set_texture_panning(Interp_subspace_offset_v, Interp_subspace_offset_u, true);
|
||||
|
||||
model_render( Subspace_model_inner, &tmp, &Eye_position, render_flags ); //MR_NO_CORRECT|MR_SHOW_OUTLINE
|
||||
model_render_immediate( &render_info, Subspace_model_inner, &tmp, &Eye_position ); //MR_NO_CORRECT|MR_SHOW_OUTLINE
|
||||
|
||||
if (!Cmdline_nohtl)
|
||||
gr_set_texture_panning(0, 0, false);
|
||||
@@ -1811,7 +1813,7 @@ void stars_draw_debris()
|
||||
void stars_draw(int show_stars, int show_suns, int show_nebulas, int show_subspace, int env)
|
||||
{
|
||||
int gr_zbuffering_save = gr_zbuffer_get();
|
||||
gr_zbuffer_set(GR_ZBUFF_NONE);
|
||||
gr_zbuffer_set(GR_ZBUFF_NONE);
|
||||
|
||||
Rendering_to_env = env;
|
||||
|
||||
@@ -2153,20 +2155,17 @@ void stars_draw_background()
|
||||
if (Nmodel_num < 0)
|
||||
return;
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
if (Nmodel_bitmap >= 0) {
|
||||
model_set_forced_texture(Nmodel_bitmap);
|
||||
Nmodel_flags |= MR_FORCE_TEXTURE;
|
||||
render_info.set_forced_bitmap(Nmodel_bitmap);
|
||||
}
|
||||
|
||||
// draw the model at the player's eye with no z-buffering
|
||||
model_set_alpha(1.0f);
|
||||
render_info.set_alpha(1.0f);
|
||||
render_info.set_flags(Nmodel_flags | MR_SKYBOX);
|
||||
|
||||
model_render(Nmodel_num, &Nmodel_orient, &Eye_position, Nmodel_flags, -1, -1, NULL, true);
|
||||
|
||||
if (Nmodel_bitmap >= 0) {
|
||||
model_set_forced_texture(-1);
|
||||
Nmodel_flags &= ~MR_FORCE_TEXTURE;
|
||||
}
|
||||
model_render_immediate(&render_info, Nmodel_num, &Nmodel_orient, &Eye_position, MODEL_RENDER_ALL);
|
||||
}
|
||||
|
||||
// call this to set a specific model as the background model
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "asteroid/asteroid.h"
|
||||
#include "object/object.h"
|
||||
|
||||
#include "model/modelrender.h"
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Module-wide globals
|
||||
@@ -387,7 +387,7 @@ void shockwave_move(object *shockwave_objp, float frametime)
|
||||
*
|
||||
* @param objp pointer to shockwave object
|
||||
*/
|
||||
void shockwave_render(object *objp)
|
||||
void shockwave_render_DEPRECATED(object *objp)
|
||||
{
|
||||
shockwave *sw;
|
||||
vertex p;
|
||||
@@ -418,7 +418,7 @@ void shockwave_render(object *objp)
|
||||
float dist = vm_vec_dist_quick( &sw->pos, &Eye_position );
|
||||
|
||||
model_set_detail_level((int)(dist / (sw->radius * 10.0f)));
|
||||
model_render( sw->model_id, &Objects[sw->objnum].orient, &sw->pos, MR_NO_LIGHTING | MR_NO_FOGGING | MR_NORMAL | MR_CENTER_ALPHA | MR_NO_CULL, sw->objnum);
|
||||
model_render_DEPRECATED( sw->model_id, &Objects[sw->objnum].orient, &sw->pos, MR_DEPRECATED_NO_LIGHTING | MR_DEPRECATED_NO_FOGGING | MR_DEPRECATED_NORMAL | MR_DEPRECATED_CENTER_ALPHA | MR_DEPRECATED_NO_CULL, sw->objnum);
|
||||
|
||||
model_set_warp_globals();
|
||||
if(Cmdline_fb_explosions)
|
||||
@@ -461,6 +461,79 @@ void shockwave_render(object *objp)
|
||||
}
|
||||
}
|
||||
|
||||
void shockwave_render(object *objp, draw_list *scene)
|
||||
{
|
||||
shockwave *sw;
|
||||
vertex p;
|
||||
|
||||
Assert(objp->type == OBJ_SHOCKWAVE);
|
||||
Assert(objp->instance >= 0 && objp->instance < MAX_SHOCKWAVES);
|
||||
|
||||
sw = &Shockwaves[objp->instance];
|
||||
|
||||
if( (sw->delay_stamp != -1) && !timestamp_elapsed(sw->delay_stamp)){
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (sw->current_bitmap < 0) && (sw->model_id < 0) )
|
||||
return;
|
||||
|
||||
if (sw->model_id > -1) {
|
||||
vec3d scale;
|
||||
scale.xyz.x = scale.xyz.y = scale.xyz.z = sw->radius / 50.0f;
|
||||
|
||||
model_render_params render_info;
|
||||
|
||||
render_info.set_warp_params(-1, 1.0f - (sw->radius/sw->outer_radius), scale);
|
||||
|
||||
float dist = vm_vec_dist_quick( &sw->pos, &Eye_position );
|
||||
|
||||
render_info.set_detail_level_lock((int)(dist / (sw->radius * 10.0f)));
|
||||
render_info.set_flags(MR_NO_LIGHTING | MR_NO_FOGGING | MR_NORMAL | MR_CENTER_ALPHA | MR_NO_CULL | MR_NO_BATCH);
|
||||
render_info.set_object_number(sw->objnum);
|
||||
|
||||
model_render_queue( &render_info, scene, sw->model_id, &Objects[sw->objnum].orient, &sw->pos);
|
||||
|
||||
if ( Cmdline_fb_explosions ) {
|
||||
g3_transfer_vertex(&p, &sw->pos);
|
||||
|
||||
distortion_add_bitmap_rotated(
|
||||
Shockwave_info[1].bitmap_id+shockwave_get_framenum(objp->instance, 94),
|
||||
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD | TMAP_FLAG_DISTORTION,
|
||||
&p,
|
||||
fl_radians(sw->rot_angles.p),
|
||||
sw->radius,
|
||||
((sw->time_elapsed/sw->total_time)>0.9f)?(1.0f-(sw->time_elapsed/sw->total_time))*10.0f:1.0f
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (!Cmdline_nohtl) {
|
||||
g3_transfer_vertex(&p, &sw->pos);
|
||||
} else {
|
||||
g3_rotate_vertex(&p, &sw->pos);
|
||||
}
|
||||
|
||||
if ( Cmdline_fb_explosions ) {
|
||||
distortion_add_bitmap_rotated(
|
||||
sw->current_bitmap,
|
||||
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD | TMAP_FLAG_DISTORTION,
|
||||
&p,
|
||||
fl_radians(sw->rot_angles.p),
|
||||
sw->radius,
|
||||
((sw->time_elapsed/sw->total_time)>0.9f)?(1.0f-(sw->time_elapsed/sw->total_time))*10.0f:1.0f
|
||||
);
|
||||
}
|
||||
|
||||
batch_add_bitmap_rotated(
|
||||
sw->current_bitmap,
|
||||
TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD,
|
||||
&p,
|
||||
fl_radians(sw->rot_angles.p),
|
||||
sw->radius
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to load a shockwave, or add it and then load it
|
||||
*/
|
||||
@@ -659,7 +732,7 @@ void shockwave_render_all()
|
||||
while ( sw != &Shockwave_list ) {
|
||||
next = sw->next;
|
||||
Assert(sw->objnum != -1);
|
||||
shockwave_render(&Objects[sw->objnum]);
|
||||
shockwave_render_DEPRECATED(&Objects[sw->objnum]);
|
||||
sw = next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "globalincs/globals.h"
|
||||
|
||||
class object;
|
||||
class draw_list;
|
||||
|
||||
#define SW_USED (1<<0)
|
||||
#define SW_WEAPON (1<<1)
|
||||
@@ -93,7 +94,8 @@ void shockwave_level_close();
|
||||
void shockwave_delete(object *objp);
|
||||
void shockwave_move_all(float frametime);
|
||||
int shockwave_create(int parent_objnum, vec3d *pos, shockwave_create_info *sci, int flag, int delay = -1);
|
||||
void shockwave_render(object *objp);
|
||||
void shockwave_render_DEPRECATED(object *objp);
|
||||
void shockwave_render(object *objp, draw_list *scene);
|
||||
int shockwave_load(char *s_name, bool shock_3D = false);
|
||||
|
||||
int shockwave_get_weapon_index(int index);
|
||||
|
||||
+175
-3
@@ -14,16 +14,23 @@
|
||||
#include "render/3d.h"
|
||||
#include "io/timer.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
|
||||
int Num_trails;
|
||||
trail Trails;
|
||||
|
||||
int Trail_buffer_object = -1;
|
||||
|
||||
// Reset everything between levels
|
||||
void trail_level_init()
|
||||
{
|
||||
Num_trails = 0;
|
||||
Trails.next = &Trails;
|
||||
|
||||
if (Trail_buffer_object < 0) {
|
||||
Trail_buffer_object = gr_create_stream_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
void trail_level_close()
|
||||
@@ -149,6 +156,167 @@ static void allocate_trail_verts(int num_verts)
|
||||
}
|
||||
}
|
||||
|
||||
void trail_add_batch(trail * trailp)
|
||||
{
|
||||
int sections[NUM_TRAIL_SECTIONS];
|
||||
int num_sections = 0;
|
||||
int i;
|
||||
vec3d topv, botv, *fvec, last_pos, tmp_fvec;
|
||||
vertex top, bot, top_prev, bot_prev;
|
||||
int nv = 0;
|
||||
float w;
|
||||
ubyte l;
|
||||
vec3d centerv;
|
||||
|
||||
if (trailp->tail == trailp->head)
|
||||
return;
|
||||
|
||||
// if this trail is on the player ship, and he's in any padlock view except rear view, don't draw
|
||||
if ((Player_ship != NULL) && trail_is_on_ship(trailp, Player_ship) &&
|
||||
(Viewer_mode & (VM_PADLOCK_UP | VM_PADLOCK_LEFT | VM_PADLOCK_RIGHT)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
trail_info *ti = &trailp->info;
|
||||
|
||||
int n = trailp->tail;
|
||||
|
||||
do {
|
||||
n--;
|
||||
|
||||
if (n < 0)
|
||||
n = NUM_TRAIL_SECTIONS - 1;
|
||||
|
||||
if (trailp->val[n] > 1.0f)
|
||||
break;
|
||||
|
||||
sections[num_sections++] = n;
|
||||
} while (n != trailp->head);
|
||||
|
||||
if (num_sections <= 0)
|
||||
return;
|
||||
|
||||
Assertion(ti->texture.bitmap_id != -1, "Weapon trail %s could not be loaded", ti->texture.filename); // We can leave this as an assert, but tell them how to fix it. --Chief
|
||||
|
||||
memset(&top, 0, sizeof(vertex));
|
||||
memset(&bot, 0, sizeof(vertex));
|
||||
memset(&top_prev, 0, sizeof(vertex));
|
||||
memset(&bot_prev, 0, sizeof(vertex));
|
||||
|
||||
float w_size = (ti->w_end - ti->w_start);
|
||||
float a_size = (ti->a_end - ti->a_start);
|
||||
int num_faded_sections = ti->n_fade_out_sections;
|
||||
|
||||
for (i = 0; i < num_sections; i++) {
|
||||
n = sections[i];
|
||||
float init_fade_out = 1.0f;
|
||||
|
||||
if ((num_faded_sections > 0) && (i < num_faded_sections)) {
|
||||
init_fade_out = ((float)i) / (float)num_faded_sections;
|
||||
}
|
||||
|
||||
w = trailp->val[n] * w_size + ti->w_start;
|
||||
if (init_fade_out != 1.0f) {
|
||||
l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f * init_fade_out * init_fade_out);
|
||||
}
|
||||
else {
|
||||
l = (ubyte)fl2i((trailp->val[n] * a_size + ti->a_start) * 255.0f);
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
if (num_sections > 1) {
|
||||
vm_vec_sub(&tmp_fvec, &trailp->pos[n], &trailp->pos[sections[i + 1]]);
|
||||
vm_vec_normalize_safe(&tmp_fvec);
|
||||
fvec = &tmp_fvec;
|
||||
}
|
||||
else {
|
||||
fvec = &tmp_fvec;
|
||||
fvec->xyz.x = 0.0f;
|
||||
fvec->xyz.y = 0.0f;
|
||||
fvec->xyz.z = 1.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vm_vec_sub(&tmp_fvec, &last_pos, &trailp->pos[n]);
|
||||
vm_vec_normalize_safe(&tmp_fvec);
|
||||
fvec = &tmp_fvec;
|
||||
}
|
||||
|
||||
trail_calc_facing_pts(&topv, &botv, fvec, &trailp->pos[n], w);
|
||||
|
||||
if (!Cmdline_nohtl) {
|
||||
g3_transfer_vertex(&top, &topv);
|
||||
g3_transfer_vertex(&bot, &botv);
|
||||
}
|
||||
else {
|
||||
g3_rotate_vertex(&top, &topv);
|
||||
g3_rotate_vertex(&bot, &botv);
|
||||
}
|
||||
|
||||
top.r = top.g = top.b = l;
|
||||
bot.r = bot.g = bot.b = l;
|
||||
top.a = bot.a = l;
|
||||
|
||||
float U = i2fl(i);
|
||||
|
||||
top.texture_position.u = U;
|
||||
top.texture_position.v = 1.0f;
|
||||
|
||||
bot.texture_position.u = U;
|
||||
bot.texture_position.v = 0.0f;
|
||||
|
||||
if (i > 0) {
|
||||
if (i == num_sections - 1) {
|
||||
// Last one...
|
||||
vm_vec_avg(¢erv, &topv, &botv);
|
||||
|
||||
vertex center_vert;
|
||||
|
||||
if (!Cmdline_nohtl)
|
||||
g3_transfer_vertex(¢er_vert, ¢erv);
|
||||
else
|
||||
g3_rotate_vertex(¢er_vert, ¢erv);
|
||||
|
||||
center_vert.texture_position.u = U + 1.0f;
|
||||
center_vert.texture_position.v = 0.5f;
|
||||
center_vert.a = center_vert.r = center_vert.g = center_vert.b = l;
|
||||
|
||||
vertex tri[3];
|
||||
|
||||
tri[1] = top_prev;
|
||||
tri[2] = bot_prev;
|
||||
tri[0] = center_vert;
|
||||
|
||||
batch_add_tri(
|
||||
ti->texture.bitmap_id,
|
||||
TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT,
|
||||
tri,
|
||||
1.0f
|
||||
);
|
||||
} else {
|
||||
vertex quad[4];
|
||||
|
||||
quad[0] = top_prev;
|
||||
quad[1] = bot_prev;
|
||||
quad[2] = bot;
|
||||
quad[3] = top;
|
||||
|
||||
batch_add_quad(
|
||||
ti->texture.bitmap_id,
|
||||
TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT,
|
||||
quad,
|
||||
1.0f
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
last_pos = trailp->pos[n];
|
||||
top_prev = top;
|
||||
bot_prev = bot;
|
||||
}
|
||||
}
|
||||
|
||||
void trail_render( trail * trailp )
|
||||
{
|
||||
int sections[NUM_TRAIL_SECTIONS];
|
||||
@@ -292,7 +460,6 @@ void trail_render( trail * trailp )
|
||||
Trail_v_list[nv+1] = bot;
|
||||
}
|
||||
|
||||
|
||||
if ( !nv )
|
||||
return;
|
||||
|
||||
@@ -303,9 +470,10 @@ void trail_render( trail * trailp )
|
||||
if ( (nv % 2) != 1 )
|
||||
Warning( LOCATION, "even number of verts in trail render\n" );
|
||||
|
||||
|
||||
profile_begin("Trail Draw");
|
||||
gr_set_bitmap( ti->texture.bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
|
||||
gr_render(nv, Trail_v_list, TMAP_FLAG_TEXTURED | TMAP_FLAG_ALPHA | TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_HTL_3D_UNLIT | TMAP_FLAG_TRISTRIP);
|
||||
profile_end("Trail Draw");
|
||||
}
|
||||
|
||||
|
||||
@@ -394,9 +562,13 @@ void trail_render_all()
|
||||
|
||||
for(trail *trailp = Trails.next; trailp!=&Trails; trailp = trailp->next )
|
||||
{
|
||||
//trail_add_batch(trailp);
|
||||
trail_render(trailp);
|
||||
}
|
||||
|
||||
//profile_begin("Batch Render Trails");
|
||||
//batch_render_all(Trail_buffer_object);
|
||||
//profile_end("Batch Render Trails");
|
||||
}
|
||||
int trail_stamp_elapsed(trail *trailp)
|
||||
{
|
||||
|
||||
@@ -605,7 +605,8 @@ int weapon_info_lookup(const char *name = NULL);
|
||||
void weapon_init(); // called at game startup
|
||||
void weapon_close(); // called at game shutdown
|
||||
void weapon_level_init(); // called before the start of each level
|
||||
void weapon_render(object * obj);
|
||||
void weapon_render_DEPRECATED(object * obj);
|
||||
void weapon_render(object* obj, draw_list *scene);
|
||||
void weapon_delete( object * obj );
|
||||
void weapon_process_pre( object *obj, float frame_time);
|
||||
void weapon_process_post( object *obj, float frame_time);
|
||||
|
||||
+202
-7
@@ -47,9 +47,9 @@
|
||||
#include "parse/scripting.h"
|
||||
#include "stats/scoring.h"
|
||||
#include "mod_table/mod_table.h"
|
||||
#include "model/modelrender.h"
|
||||
#include "debugconsole/console.h"
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
int Weapon_flyby_sound_enabled = 1;
|
||||
DCF_BOOL( weapon_flyby, Weapon_flyby_sound_enabled )
|
||||
@@ -3533,7 +3533,7 @@ const float weapon_glow_scale_r = 2.3f;
|
||||
const float weapon_glow_scale_l = 1.5f;
|
||||
const int weapon_glow_alpha = 217; // (0.85 * 255);
|
||||
|
||||
void weapon_render(object *obj)
|
||||
void weapon_render_DEPRECATED(object *obj)
|
||||
{
|
||||
int num;
|
||||
weapon_info *wip;
|
||||
@@ -3663,14 +3663,14 @@ void weapon_render(object *obj)
|
||||
|
||||
case WRT_POF:
|
||||
{
|
||||
uint render_flags = MR_NORMAL|MR_IS_MISSILE|MR_NO_LIGHTING;
|
||||
uint render_flags = MR_DEPRECATED_NORMAL|MR_DEPRECATED_IS_MISSILE|MR_DEPRECATED_NO_LIGHTING;
|
||||
|
||||
if (Cmdline_missile_lighting && !(wip->wi_flags2 & WIF2_MR_NO_LIGHTING))
|
||||
render_flags &= ~MR_NO_LIGHTING;
|
||||
render_flags &= ~MR_DEPRECATED_NO_LIGHTING;
|
||||
|
||||
if (wip->wi_flags2 & WIF2_TRANSPARENT) {
|
||||
model_set_alpha(wp->alpha_current);
|
||||
render_flags |= MR_ALL_XPARENT;
|
||||
render_flags |= MR_DEPRECATED_ALL_XPARENT;
|
||||
}
|
||||
|
||||
model_clear_instance(wip->model_num);
|
||||
@@ -3696,7 +3696,7 @@ void weapon_render(object *obj)
|
||||
|
||||
model_set_thrust(wip->model_num, &mst);
|
||||
|
||||
render_flags |= MR_SHOW_THRUSTERS;
|
||||
render_flags |= MR_DEPRECATED_SHOW_THRUSTERS;
|
||||
}
|
||||
|
||||
|
||||
@@ -3716,7 +3716,7 @@ void weapon_render(object *obj)
|
||||
}
|
||||
|
||||
|
||||
model_render(wip->model_num, &obj->orient, &obj->pos, render_flags);
|
||||
model_render_DEPRECATED(wip->model_num, &obj->orient, &obj->pos, render_flags);
|
||||
wp->weapon_flags |= WF_CONSIDER_FOR_FLYBY_SOUND;
|
||||
if (clip_plane)
|
||||
{
|
||||
@@ -7055,3 +7055,198 @@ void weapon_unpause_sounds()
|
||||
// Pause all beam sounds
|
||||
beam_unpause_sounds();
|
||||
}
|
||||
|
||||
void weapon_render(object* obj, draw_list *scene)
|
||||
{
|
||||
int num;
|
||||
weapon_info *wip;
|
||||
weapon *wp;
|
||||
color c;
|
||||
|
||||
MONITOR_INC(NumWeaponsRend, 1);
|
||||
|
||||
Assert(obj->type == OBJ_WEAPON);
|
||||
|
||||
num = obj->instance;
|
||||
wp = &Weapons[num];
|
||||
wip = &Weapon_info[Weapons[num].weapon_info_index];
|
||||
|
||||
if (wip->wi_flags2 & WIF2_TRANSPARENT) {
|
||||
if (wp->alpha_current == -1.0f) {
|
||||
wp->alpha_current = wip->alpha_max;
|
||||
} else if (wip->alpha_cycle > 0.0f) {
|
||||
if (wp->alpha_backward) {
|
||||
wp->alpha_current += wip->alpha_cycle;
|
||||
|
||||
if (wp->alpha_current > wip->alpha_max) {
|
||||
wp->alpha_current = wip->alpha_max;
|
||||
wp->alpha_backward = 0;
|
||||
}
|
||||
} else {
|
||||
wp->alpha_current -= wip->alpha_cycle;
|
||||
|
||||
if (wp->alpha_current < wip->alpha_min) {
|
||||
wp->alpha_current = wip->alpha_min;
|
||||
wp->alpha_backward = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (wip->render_type)
|
||||
{
|
||||
case WRT_LASER:
|
||||
{
|
||||
if(wip->laser_length < 0.0001f)
|
||||
return;
|
||||
|
||||
int alpha = 255;
|
||||
int framenum = 0;
|
||||
|
||||
if (wip->laser_bitmap.first_frame >= 0) {
|
||||
gr_set_color_fast(&wip->laser_color_1);
|
||||
|
||||
if (wip->laser_bitmap.num_frames > 1) {
|
||||
wp->laser_bitmap_frame += flFrametime;
|
||||
|
||||
// Sanity checks
|
||||
if (wp->laser_bitmap_frame < 0.0f)
|
||||
wp->laser_bitmap_frame = 0.0f;
|
||||
if (wp->laser_bitmap_frame > 100.0f)
|
||||
wp->laser_bitmap_frame = 0.0f;
|
||||
|
||||
while (wp->laser_bitmap_frame > wip->laser_bitmap.total_time)
|
||||
wp->laser_bitmap_frame -= wip->laser_bitmap.total_time;
|
||||
|
||||
framenum = fl2i( (wp->laser_bitmap_frame * wip->laser_bitmap.num_frames) / wip->laser_bitmap.total_time );
|
||||
|
||||
CLAMP(framenum, 0, wip->laser_bitmap.num_frames-1);
|
||||
}
|
||||
|
||||
if (wip->wi_flags2 & WIF2_TRANSPARENT)
|
||||
alpha = fl2i(wp->alpha_current * 255.0f);
|
||||
|
||||
vec3d headp;
|
||||
|
||||
vm_vec_scale_add(&headp, &obj->pos, &obj->orient.vec.fvec, wip->laser_length);
|
||||
wp->weapon_flags &= ~WF_CONSIDER_FOR_FLYBY_SOUND;
|
||||
|
||||
if ( batch_add_laser(wip->laser_bitmap.first_frame + framenum, &headp, wip->laser_head_radius, &obj->pos, wip->laser_tail_radius, alpha, alpha, alpha) ) {
|
||||
wp->weapon_flags |= WF_CONSIDER_FOR_FLYBY_SOUND;
|
||||
}
|
||||
}
|
||||
|
||||
// maybe draw laser glow bitmap
|
||||
if (wip->laser_glow_bitmap.first_frame >= 0) {
|
||||
// get the laser color
|
||||
weapon_get_laser_color(&c, obj);
|
||||
|
||||
// *Tail point "getting bigger" as well as headpoint isn't being taken into consideration, so
|
||||
// it caused uneven glow between the head and tail, which really shows in big lasers. So...fixed! -Et1
|
||||
vec3d headp2, tailp;
|
||||
|
||||
vm_vec_scale_add(&headp2, &obj->pos, &obj->orient.vec.fvec, wip->laser_length * weapon_glow_scale_l);
|
||||
vm_vec_scale_add(&tailp, &obj->pos, &obj->orient.vec.fvec, wip->laser_length * (1 - weapon_glow_scale_l) );
|
||||
|
||||
framenum = 0;
|
||||
|
||||
if (wip->laser_glow_bitmap.num_frames > 1) {
|
||||
wp->laser_glow_bitmap_frame += flFrametime;
|
||||
|
||||
// Sanity checks
|
||||
if (wp->laser_glow_bitmap_frame < 0.0f)
|
||||
wp->laser_glow_bitmap_frame = 0.0f;
|
||||
if (wp->laser_glow_bitmap_frame > 100.0f)
|
||||
wp->laser_glow_bitmap_frame = 0.0f;
|
||||
|
||||
while (wp->laser_glow_bitmap_frame > wip->laser_glow_bitmap.total_time)
|
||||
wp->laser_glow_bitmap_frame -= wip->laser_glow_bitmap.total_time;
|
||||
|
||||
framenum = fl2i( (wp->laser_glow_bitmap_frame * wip->laser_glow_bitmap.num_frames) / wip->laser_glow_bitmap.total_time );
|
||||
|
||||
CLAMP(framenum, 0, wip->laser_glow_bitmap.num_frames-1);
|
||||
}
|
||||
|
||||
if (wip->wi_flags2 & WIF2_TRANSPARENT) {
|
||||
alpha = fl2i(wp->alpha_current * 255.0f);
|
||||
alpha -= 38; // take 1.5f into account for the normal glow alpha
|
||||
|
||||
if (alpha < 0)
|
||||
alpha = 0;
|
||||
} else {
|
||||
alpha = weapon_glow_alpha;
|
||||
}
|
||||
|
||||
batch_add_laser(wip->laser_glow_bitmap.first_frame + framenum, &headp2, wip->laser_head_radius * weapon_glow_scale_f, &tailp, wip->laser_tail_radius * weapon_glow_scale_r, (c.red*alpha)/255, (c.green*alpha)/255, (c.blue*alpha)/255);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WRT_POF:
|
||||
{
|
||||
model_render_params render_info;
|
||||
|
||||
uint render_flags = MR_NORMAL|MR_IS_MISSILE|MR_NO_LIGHTING|MR_NO_BATCH;
|
||||
|
||||
if (Cmdline_missile_lighting && !(wip->wi_flags2 & WIF2_MR_NO_LIGHTING))
|
||||
render_flags &= ~MR_NO_LIGHTING;
|
||||
|
||||
if (wip->wi_flags2 & WIF2_TRANSPARENT) {
|
||||
render_info.set_alpha(wp->alpha_current);
|
||||
render_flags |= MR_ALL_XPARENT;
|
||||
}
|
||||
|
||||
model_clear_instance(wip->model_num);
|
||||
|
||||
if ( (wip->wi_flags & WIF_THRUSTER) && ((wp->thruster_bitmap > -1) || (wp->thruster_glow_bitmap > -1)) ) {
|
||||
float ft;
|
||||
mst_info mst;
|
||||
|
||||
// Add noise to thruster geometry.
|
||||
ft = 1.0f; // Always use 1.0f for missiles
|
||||
ft *= (1.0f + frand()/5.0f - 1.0f/10.0f);
|
||||
if (ft > 1.0f)
|
||||
ft = 1.0f;
|
||||
|
||||
mst.length.xyz.x = ft;
|
||||
mst.length.xyz.y = ft;
|
||||
mst.length.xyz.z = ft;
|
||||
|
||||
mst.primary_bitmap = wp->thruster_bitmap;
|
||||
mst.primary_glow_bitmap = wp->thruster_glow_bitmap;
|
||||
mst.glow_rad_factor = wip->thruster_glow_factor;
|
||||
mst.glow_noise = wp->thruster_glow_noise;
|
||||
|
||||
render_info.set_thruster_info(mst);
|
||||
|
||||
render_flags |= MR_SHOW_THRUSTERS;
|
||||
}
|
||||
|
||||
|
||||
//don't render local ssm's when they are still in subspace
|
||||
if (wp->lssm_stage==3)
|
||||
break;
|
||||
|
||||
int clip_plane=0;
|
||||
|
||||
// start a clip plane
|
||||
if ( wp->lssm_stage == 2 ) {
|
||||
object *wobj=&Objects[wp->lssm_warp_idx]; //warphole object
|
||||
clip_plane=1;
|
||||
|
||||
render_info.set_clip_plane(wobj->pos, wobj->orient.vec.fvec);
|
||||
}
|
||||
|
||||
render_info.set_flags(render_flags);
|
||||
|
||||
model_render_queue(&render_info, scene, wip->model_num, &obj->orient, &obj->pos);
|
||||
wp->weapon_flags |= WF_CONSIDER_FOR_FLYBY_SOUND;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Warning(LOCATION, "Unknown weapon rendering type = %i for weapon %s\n", wip->render_type, wip->name);
|
||||
}
|
||||
}
|
||||
@@ -399,9 +399,9 @@
|
||||
<ClCompile Include="..\..\code\cutscene\mveplayer.cpp" />
|
||||
<ClCompile Include="..\..\code\cutscene\oggplayer.cpp" />
|
||||
<ClCompile Include="..\..\code\Debris\debris.cpp" />
|
||||
<ClCompile Include="..\..\code\debugconsole\console.cpp" />
|
||||
<ClCompile Include="..\..\code\debugconsole\consolecmds.cpp" />
|
||||
<ClCompile Include="..\..\code\debugconsole\consoleparse.cpp" />
|
||||
<ClCompile Include="..\..\code\debugconsole\console.cpp" />
|
||||
<ClCompile Include="..\..\code\debugconsole\consolecmds.cpp" />
|
||||
<ClCompile Include="..\..\code\debugconsole\consoleparse.cpp" />
|
||||
<ClCompile Include="..\..\code\debugconsole\timerbar.cpp" />
|
||||
<ClCompile Include="..\..\code\fireball\fireballs.cpp" />
|
||||
<ClCompile Include="..\..\code\fireball\warpineffect.cpp" />
|
||||
@@ -414,8 +414,8 @@
|
||||
<ClCompile Include="..\..\code\globalincs\def_files.cpp" />
|
||||
<ClCompile Include="..\..\code\globalincs\fsmemory.cpp" />
|
||||
<ClCompile Include="..\..\code\globalincs\mspdb_callstack.cpp" />
|
||||
<ClCompile Include="..\..\code\globalincs\profiling.cpp" />
|
||||
<ClCompile Include="..\..\code\globalincs\safe_strings.cpp" />
|
||||
<ClCompile Include="..\..\code\globalincs\profiling.cpp" />
|
||||
<ClCompile Include="..\..\code\globalincs\safe_strings.cpp" />
|
||||
<ClCompile Include="..\..\code\globalincs\safe_strings_test.cpp" />
|
||||
<ClCompile Include="..\..\code\globalincs\systemvars.cpp" />
|
||||
<ClCompile Include="..\..\code\globalincs\version.cpp" />
|
||||
@@ -435,6 +435,7 @@
|
||||
<ClCompile Include="..\..\code\graphics\gropenglstate.cpp" />
|
||||
<ClCompile Include="..\..\code\graphics\gropengltexture.cpp" />
|
||||
<ClCompile Include="..\..\code\graphics\gropengltnl.cpp" />
|
||||
<ClCompile Include="..\..\code\graphics\shadows.cpp" />
|
||||
<ClCompile Include="..\..\code\hud\hud.cpp" />
|
||||
<ClCompile Include="..\..\code\hud\hudartillery.cpp" />
|
||||
<ClCompile Include="..\..\code\hud\hudbrackets.cpp" />
|
||||
@@ -509,6 +510,7 @@
|
||||
<ClCompile Include="..\..\code\model\modelinterp.cpp" />
|
||||
<ClCompile Include="..\..\code\model\modeloctant.cpp" />
|
||||
<ClCompile Include="..\..\code\model\modelread.cpp" />
|
||||
<ClCompile Include="..\..\code\model\modelrender.cpp" />
|
||||
<ClCompile Include="..\..\code\mod_table\mod_table.cpp" />
|
||||
<ClCompile Include="..\..\code\object\collidedebrisship.cpp" />
|
||||
<ClCompile Include="..\..\code\object\collidedebrisweapon.cpp" />
|
||||
@@ -540,12 +542,12 @@
|
||||
<ClCompile Include="..\..\code\Particle\particle.cpp" />
|
||||
<ClCompile Include="..\..\code\PcxUtils\pcxutils.cpp" />
|
||||
<ClCompile Include="..\..\code\Physics\physics.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\csg.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\csg_convert.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\pilotfile.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\pilotfile_convert.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\plr.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\plr_convert.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\csg.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\csg_convert.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\pilotfile.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\pilotfile_convert.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\plr.cpp" />
|
||||
<ClCompile Include="..\..\code\PilotFile\plr_convert.cpp" />
|
||||
<ClCompile Include="..\..\code\playerman\managepilot.cpp" />
|
||||
<ClCompile Include="..\..\code\playerman\playercontrol.cpp" />
|
||||
<ClCompile Include="..\..\code\popup\popup.cpp" />
|
||||
@@ -682,8 +684,8 @@
|
||||
<ClInclude Include="..\..\code\cutscene\mvelib.h" />
|
||||
<ClInclude Include="..\..\code\cutscene\oggplayer.h" />
|
||||
<ClInclude Include="..\..\code\Debris\debris.h" />
|
||||
<ClInclude Include="..\..\code\debugconsole\console.h" />
|
||||
<ClInclude Include="..\..\code\debugconsole\consoleparse.h" />
|
||||
<ClInclude Include="..\..\code\debugconsole\console.h" />
|
||||
<ClInclude Include="..\..\code\debugconsole\consoleparse.h" />
|
||||
<ClInclude Include="..\..\code\debugconsole\timerbar.h" />
|
||||
<ClInclude Include="..\..\code\DirectX\vasync.h" />
|
||||
<ClInclude Include="..\..\code\DirectX\vdinput.h" />
|
||||
@@ -711,6 +713,7 @@
|
||||
<ClInclude Include="..\..\code\Graphics\2d.h" />
|
||||
<ClInclude Include="..\..\code\graphics\grbatch.h" />
|
||||
<ClInclude Include="..\..\code\graphics\grinternal.h" />
|
||||
<ClInclude Include="..\..\code\graphics\shadows.h" />
|
||||
<ClInclude Include="..\..\code\graphics\tmapper.h" />
|
||||
<ClInclude Include="..\..\code\Graphics\font.h" />
|
||||
<ClInclude Include="..\..\code\graphics\generic.h" />
|
||||
@@ -801,6 +804,7 @@
|
||||
<ClInclude Include="..\..\code\missionui\redalert.h" />
|
||||
<ClInclude Include="..\..\code\model\model.h" />
|
||||
<ClInclude Include="..\..\code\model\modelanim.h" />
|
||||
<ClInclude Include="..\..\code\model\modelrender.h" />
|
||||
<ClInclude Include="..\..\code\model\modelsinc.h" />
|
||||
<ClInclude Include="..\..\code\mod_table\mod_table.h" />
|
||||
<ClInclude Include="..\..\code\object\deadobjectdock.h" />
|
||||
@@ -826,8 +830,8 @@
|
||||
<ClInclude Include="..\..\code\Particle\particle.h" />
|
||||
<ClInclude Include="..\..\code\PcxUtils\pcxutils.h" />
|
||||
<ClInclude Include="..\..\code\Physics\physics.h" />
|
||||
<ClInclude Include="..\..\code\PilotFile\pilotfile.h" />
|
||||
<ClInclude Include="..\..\code\PilotFile\pilotfile_convert.h" />
|
||||
<ClInclude Include="..\..\code\PilotFile\pilotfile.h" />
|
||||
<ClInclude Include="..\..\code\PilotFile\pilotfile_convert.h" />
|
||||
<ClInclude Include="..\..\code\playerman\managepilot.h" />
|
||||
<ClInclude Include="..\..\code\playerman\player.h" />
|
||||
<ClInclude Include="..\..\code\popup\popup.h" />
|
||||
|
||||
@@ -121,9 +121,9 @@
|
||||
<Filter Include="Physics">
|
||||
<UniqueIdentifier>{73764146-6133-4a00-9463-532184af6694}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="PilotFile">
|
||||
<UniqueIdentifier>{73764146-6640-4a00-9463-532184af6694}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="PilotFile">
|
||||
<UniqueIdentifier>{73764146-6640-4a00-9463-532184af6694}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Playerman">
|
||||
<UniqueIdentifier>{9db79e68-6640-4232-9f4c-7811fcd113f4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -288,13 +288,13 @@
|
||||
<ClCompile Include="..\..\code\Debris\debris.cpp">
|
||||
<Filter>Debris</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\debugconsole\console.cpp">
|
||||
<Filter>DebugConsole</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\debugconsole\consolecmds.cpp">
|
||||
<Filter>DebugConsole</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\debugconsole\consoleparse.cpp">
|
||||
<ClCompile Include="..\..\code\debugconsole\console.cpp">
|
||||
<Filter>DebugConsole</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\debugconsole\consolecmds.cpp">
|
||||
<Filter>DebugConsole</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\debugconsole\consoleparse.cpp">
|
||||
<Filter>DebugConsole</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\debugconsole\timerbar.cpp">
|
||||
@@ -333,9 +333,9 @@
|
||||
<ClCompile Include="..\..\code\globalincs\mspdb_callstack.cpp">
|
||||
<Filter>GlobalIncs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\globalincs\profiling.cpp">
|
||||
<Filter>GlobalIncs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\globalincs\profiling.cpp">
|
||||
<Filter>GlobalIncs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\globalincs\safe_strings.cpp">
|
||||
<Filter>GlobalIncs</Filter>
|
||||
</ClCompile>
|
||||
@@ -705,24 +705,24 @@
|
||||
<ClCompile Include="..\..\code\Physics\physics.cpp">
|
||||
<Filter>Physics</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\csg.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\csg_convert.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\pilotfile.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\pilotfile_convert.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\plr.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\plr_convert.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\csg.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\csg_convert.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\pilotfile.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\pilotfile_convert.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\plr.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\PilotFile\plr_convert.cpp">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\playerman\managepilot.cpp">
|
||||
<Filter>Playerman</Filter>
|
||||
</ClCompile>
|
||||
@@ -1065,6 +1065,12 @@
|
||||
<ClCompile Include="..\..\code\parse\generic_log.cpp">
|
||||
<Filter>Parse</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\model\modelrender.cpp">
|
||||
<Filter>Model</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\graphics\shadows.cpp">
|
||||
<Filter>Graphics</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\code\ai\ai.h">
|
||||
@@ -1133,12 +1139,12 @@
|
||||
<ClInclude Include="..\..\code\Debris\debris.h">
|
||||
<Filter>Debris</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\debugconsole\console.h">
|
||||
<Filter>DebugConsole</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\debugconsole\consoleparse.h">
|
||||
<Filter>DebugConsole</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\debugconsole\console.h">
|
||||
<Filter>DebugConsole</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\debugconsole\consoleparse.h">
|
||||
<Filter>DebugConsole</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\debugconsole\timerbar.h">
|
||||
<Filter>DebugConsole</Filter>
|
||||
</ClInclude>
|
||||
@@ -1862,18 +1868,24 @@
|
||||
<ClInclude Include="..\..\code\radar\radardradis.h">
|
||||
<Filter>Radar</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\PilotFile\pilotfile_convert.h">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\PilotFile\pilotfile.h">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\PilotFile\pilotfile_convert.h">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\PilotFile\pilotfile.h">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\mod_table\mod_table.h">
|
||||
<Filter>mod_table</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\parse\generic_log.h">
|
||||
<Filter>Parse</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\model\modelrender.h">
|
||||
<Filter>Model</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\graphics\shadows.h">
|
||||
<Filter>Graphics</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="..\..\code\directx\dxguid.lib">
|
||||
|
||||
@@ -570,6 +570,7 @@
|
||||
<ClCompile Include="..\..\code\graphics\gropenglstate.cpp" />
|
||||
<ClCompile Include="..\..\code\graphics\gropengltexture.cpp" />
|
||||
<ClCompile Include="..\..\code\graphics\gropengltnl.cpp" />
|
||||
<ClCompile Include="..\..\code\graphics\shadows.cpp" />
|
||||
<ClCompile Include="..\..\code\hud\hud.cpp" />
|
||||
<ClCompile Include="..\..\code\hud\hudartillery.cpp" />
|
||||
<ClCompile Include="..\..\code\hud\hudbrackets.cpp" />
|
||||
@@ -644,6 +645,7 @@
|
||||
<ClCompile Include="..\..\code\model\modelinterp.cpp" />
|
||||
<ClCompile Include="..\..\code\model\modeloctant.cpp" />
|
||||
<ClCompile Include="..\..\code\model\modelread.cpp" />
|
||||
<ClCompile Include="..\..\code\model\modelrender.cpp" />
|
||||
<ClCompile Include="..\..\code\mod_table\mod_table.cpp" />
|
||||
<ClCompile Include="..\..\code\object\collidedebrisship.cpp" />
|
||||
<ClCompile Include="..\..\code\object\collidedebrisweapon.cpp" />
|
||||
@@ -845,6 +847,7 @@
|
||||
<ClInclude Include="..\..\code\Graphics\2d.h" />
|
||||
<ClInclude Include="..\..\code\graphics\grbatch.h" />
|
||||
<ClInclude Include="..\..\code\graphics\grinternal.h" />
|
||||
<ClInclude Include="..\..\code\graphics\shadows.h" />
|
||||
<ClInclude Include="..\..\code\graphics\tmapper.h" />
|
||||
<ClInclude Include="..\..\code\Graphics\font.h" />
|
||||
<ClInclude Include="..\..\code\graphics\generic.h" />
|
||||
@@ -935,6 +938,7 @@
|
||||
<ClInclude Include="..\..\code\missionui\redalert.h" />
|
||||
<ClInclude Include="..\..\code\model\model.h" />
|
||||
<ClInclude Include="..\..\code\model\modelanim.h" />
|
||||
<ClInclude Include="..\..\code\model\modelrender.h" />
|
||||
<ClInclude Include="..\..\code\model\modelsinc.h" />
|
||||
<ClInclude Include="..\..\code\mod_table\mod_table.h" />
|
||||
<ClInclude Include="..\..\code\object\deadobjectdock.h" />
|
||||
|
||||
@@ -1062,6 +1062,12 @@
|
||||
<ClCompile Include="..\..\code\globalincs\profiling.cpp">
|
||||
<Filter>GlobalIncs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\model\modelrender.cpp">
|
||||
<Filter>Model</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\code\graphics\shadows.cpp">
|
||||
<Filter>Graphics</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\code\ai\ai.h">
|
||||
@@ -1868,6 +1874,12 @@
|
||||
<ClInclude Include="..\..\code\PilotFile\pilotfile.h">
|
||||
<Filter>PilotFile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\model\modelrender.h">
|
||||
<Filter>Model</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\code\graphics\shadows.h">
|
||||
<Filter>Graphics</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="..\..\code\directx\dxguid.lib">
|
||||
|
||||
Reference in new issue
Block a user