Soft shadows, deferred lighting, and various major graphics optimizations.

This commit is contained in:
Swifty committed 2015-05-02 14:35:37 -07:00
1 parent 584ec36f62
commit c620372357
98 files changed
+14284 -2993

No files matched your search

+2
View File
@@ -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 \
+27 -2
View File
@@ -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
}
}
+3 -1
View File
@@ -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);
+87
View File
@@ -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
*/
+20
View File
@@ -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.
*
+40 -3
View File
@@ -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;
+4
View File
@@ -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;
+6 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}
+3 -1
View File
@@ -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 );
+72 -1
View File
@@ -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();
}
}
+5 -1
View File
@@ -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
+172 -6
View File
@@ -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( &center, 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], &center, &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], &center, &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], &center, &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], &center, &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
View File
@@ -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;
+32 -19
View File
@@ -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();
File diff suppressed because it is too large. Load diff
+105 -48
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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] = {
+58
View File
@@ -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;
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -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 ));
+2 -1
View File
@@ -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();
File diff suppressed because it is too large. Load diff
+59 -16
View File
@@ -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
+59 -4
View File
@@ -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) {
+84 -6
View File
@@ -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 )
+18 -6
View File
@@ -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;
+2
View File
@@ -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();
+210 -412
View File
@@ -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));
+2
View File
@@ -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
View File
@@ -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;
}
}
+84 -14
View File
@@ -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
View File
@@ -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)
+93 -14
View File
@@ -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);
+58 -21
View File
@@ -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
// -----------------------------------------------------------------------------
+3 -1
View File
@@ -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);
File diff suppressed because it is too large. Load diff
+24 -9
View File
@@ -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
View File
@@ -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;
}
+492
View File
@@ -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);
}
+39
View File
@@ -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
+7 -2
View File
@@ -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
+7 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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
+80 -4
View File
@@ -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
*
+5 -1
View File
@@ -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
View File
@@ -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;
+260
View File
@@ -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
View File
@@ -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
+5 -1
View File
@@ -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);
+28
View File
@@ -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()
//
+11
View File
@@ -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
View File
@@ -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
+2 -2
View File
@@ -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:"))
+8 -7
View File
@@ -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;
+83 -24
View File
@@ -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();
+1 -1
View File
@@ -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();
+11 -9
View File
@@ -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);
}
+33 -12
View File
@@ -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
View File
@@ -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
+7 -3
View File
@@ -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(&current_pos);
model_collide_preprocess_subobj(&current_pos, &current_orient, pm, pmi, pm->detail[0]);
model_collide_preprocess_subobj(&current_pos, &current_orient, pm, pmi, pm->detail[detail_num]);
}
+1054 -317
View File
File diff suppressed because it is too large. Load diff
+404 -16
View File
@@ -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
+409
View File
@@ -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
View File
@@ -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;
+8 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+9 -3
View File
@@ -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 );
}
}
}
+1
View File
@@ -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
+12
View File
@@ -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, &center);
batch_add_beam(texture, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT, &center, &end, ray[i].width*rad, intinsity);
}
}
geometry_batcher flash_ball::batcher;
+5 -5
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+4 -1
View File
@@ -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 );
+3
View File
@@ -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
View File
@@ -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(&center_to_debris, &tmp, &half_ship->local_pivot);
vm_vec_crossprod(&debris_vel, &center_to_debris, &half_ship->phys_info.rotvel);
vm_vec_add2(&debris_vel, &half_ship->phys_info.vel);
vm_vec_copy_normalize(&radial_vel, &center_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;
}
+8
View File
@@ -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();
+16 -17
View File
@@ -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
+77 -4
View File
@@ -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;
}
}
+3 -1
View File
@@ -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
View File
@@ -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(&centerv, &topv, &botv);
vertex center_vert;
if (!Cmdline_nohtl)
g3_transfer_vertex(&center_vert, &centerv);
else
g3_rotate_vertex(&center_vert, &centerv);
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)
{
+2 -1
View File
@@ -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
View File
@@ -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);
}
}
+19 -15
View File
@@ -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" />
+55 -43
View File
@@ -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">
+4
View File
@@ -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" />
+12
View File
@@ -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">