Compare commits

...
Author SHA1 Message Date
asarium c084a432d4 Add lights to thrusters 2020-05-02 15:33:52 +02:00
9 changed files with 247 additions and 46 deletions

No files matched your search

+16 -8
View File
@@ -7,15 +7,12 @@
*
*/
#ifdef _WIN32
#include <windows.h>
#include <windowsx.h>
#endif
#include "2d.h"
#include "globalincs/alphacolors.h"
#include "globalincs/systemvars.h"
#include "2d.h"
#include "debug.h"
#include "grinternal.h"
#include "grstub.h"
#include "light.h"
@@ -47,6 +44,11 @@
#include <algorithm>
#include <climits>
#ifdef _WIN32
#include <windows.h>
#include <windowsx.h>
#endif
#if (SDL_VERSION_ATLEAST(1, 2, 7))
#include "SDL_cpuinfo.h"
#endif
@@ -990,13 +992,17 @@ bool gr_unsize_screen_posf(float *x, float *y, float *w, float *h, int resize_mo
void gr_close()
{
if ( !Gr_inited ) {
if (!Gr_inited) {
return;
}
graphics::debug::cleanup();
if (Gr_original_gamma_ramp != nullptr && os::getSDLMainWindow() != nullptr) {
SDL_SetWindowGammaRamp(os::getSDLMainWindow(), Gr_original_gamma_ramp, (Gr_original_gamma_ramp + 256),
(Gr_original_gamma_ramp + 512));
SDL_SetWindowGammaRamp(os::getSDLMainWindow(),
Gr_original_gamma_ramp,
(Gr_original_gamma_ramp + 256),
(Gr_original_gamma_ramp + 512));
}
// This is valid even if Gr_original_gamma_ramp is nullptr
@@ -2629,6 +2635,8 @@ void gr_flip(bool execute_scripting)
Script_system.EndFrame();
}
graphics::debug::render_elements();
gr_reset_immediate_buffer();
// Do per frame operations on the matrix state
+146
View File
@@ -0,0 +1,146 @@
#include "debug.h"
#include "render/3dinternal.h"
namespace graphics {
namespace debug {
namespace {
enum DebugElementType {
Line,
Text,
};
struct LineParams {
vertex projected_from;
vertex projected_to;
color line_color;
};
struct TextParams {
vertex projected_pos;
color text_color;
SCP_string text;
};
struct DebugElement {
DebugElementType type;
// A variant/union would be good here but our C++ version does not support that yet
LineParams lineParams;
TextParams textParams;
};
bool vertex_offscreen(const vertex& v) { return v.flags & PF_OVERFLOW; }
SCP_vector<DebugElement> debugElements;
void render_line(LineParams& lineParams)
{
if (vertex_offscreen(lineParams.projected_from) && vertex_offscreen(lineParams.projected_to)) {
return;
}
gr_set_color_fast(&lineParams.line_color);
gr_line(lineParams.projected_from.screen.xyw.x,
lineParams.projected_from.screen.xyw.y,
lineParams.projected_to.screen.xyw.x,
lineParams.projected_to.screen.xyw.y,
GR_RESIZE_NONE);
}
void render_text(TextParams& params)
{
if (vertex_offscreen(params.projected_pos)) {
return;
}
font::set_font(font::FONT1);
gr_set_color_fast(&params.text_color);
gr_string(params.projected_pos.screen.xyw.x,
params.projected_pos.screen.xyw.y,
params.text.c_str(),
GR_RESIZE_NONE);
}
void render_element(DebugElement& el)
{
switch (el.type) {
case Line:
render_line(el.lineParams);
break;
case Text:
render_text(el.textParams);
break;
default:
UNREACHABLE("Unknown debug element type!");
}
}
} // namespace
void line_3d(const vec3d* from, const vec3d* to, const color* color)
{
DebugElement el;
el.type = DebugElementType::Line;
bool do_g3 = G3_count < 1;
if (do_g3)
g3_start_frame(0);
g3_rotate_vertex(&el.lineParams.projected_from, from);
g3_project_vertex(&el.lineParams.projected_from);
g3_rotate_vertex(&el.lineParams.projected_to, to);
g3_project_vertex(&el.lineParams.projected_to);
if (do_g3)
g3_end_frame();
el.lineParams.line_color = *color;
debugElements.push_back(el);
}
void text_3d(const vec3d* world_pos, const color* color, SCP_string text)
{
DebugElement el;
el.type = DebugElementType::Text;
bool do_g3 = G3_count < 1;
if (do_g3)
g3_start_frame(0);
g3_rotate_vertex(&el.textParams.projected_pos, world_pos);
g3_project_vertex(&el.textParams.projected_pos);
if (do_g3)
g3_end_frame();
el.textParams.text_color = *color;
el.textParams.text = std::move(text);
debugElements.push_back(el);
}
void render_elements()
{
if (debugElements.empty()) {
return;
}
for (auto& dbgEl : debugElements) {
render_element(dbgEl);
}
debugElements.clear();
}
void cleanup() { debugElements.clear(); }
} // namespace debug
} // namespace graphics
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "graphics/2d.h"
#include "math/vecmat.h"
namespace graphics {
namespace debug {
void line_3d(const vec3d* from, const vec3d* to, const color* color);
void text_3d(const vec3d* world_pos, const color* color, SCP_string text);
void render_elements();
void cleanup();
} // namespace debug
} // namespace graphics
+5 -1
View File
@@ -490,9 +490,13 @@ void light_add_cone(const vec3d *pos, const vec3d *dir, float angle, float inner
Num_lights++;
vec3d screen_dir;
vm_vec_rotate(&screen_dir, dir, &Eye_matrix);
screen_dir.xyz.z = -screen_dir.xyz.z;
l.type = Light_Type::Cone;
l.vec = *pos;
l.vec2= *dir;
l.vec2= screen_dir;
l.cone_angle = angle;
l.cone_inner_angle = inner_angle;
l.dual_cone = dual_cone;
+8 -2
View File
@@ -541,19 +541,25 @@ inline vec3d& operator-=(vec3d& left, const vec3d& right)
return left;
}
inline vec3d operator*(vec3d& left, float right)
inline vec3d operator*(const vec3d& left, float right)
{
vec3d out;
vm_vec_copy_scale(&out, &left, right);
return out;
}
inline vec3d operator*(float left, const vec3d& right)
{
vec3d out;
vm_vec_copy_scale(&out, &right, left);
return out;
}
inline vec3d& operator*=(vec3d& left, float right)
{
vm_vec_scale(&left, right);
return left;
}
inline vec3d operator/(vec3d& left, float right)
inline vec3d operator/(const vec3d& left, float right)
{
vec3d out;
vm_vec_copy_scale(&out, &left, 1.0f / right);
+48 -25
View File
@@ -9,9 +9,12 @@
#include "model/modelrender.h"
#include "globalincs/alphacolors.h"
#include "asteroid/asteroid.h"
#include "cmdline/cmdline.h"
#include "gamesequence/gamesequence.h"
#include "graphics/debug.h"
#include "graphics/light.h"
#include "graphics/matrix.h"
#include "graphics/shadows.h"
@@ -1809,7 +1812,6 @@ void model_render_glowpoint(int point_num, vec3d *pos, matrix *orient, glow_poin
vec3d cone_dir_rot;
vec3d cone_dir_model;
vec3d cone_dir_world;
vec3d cone_dir_screen;
vec3d unused;
if ( gpo->rotating ) {
@@ -1820,9 +1822,7 @@ void model_render_glowpoint(int point_num, vec3d *pos, matrix *orient, glow_poin
find_submodel_instance_point_normal(&unused, &cone_dir_model, shipp->model_instance_num, bank->submodel_parent, &unused, &cone_dir_rot);
vm_vec_unrotate(&cone_dir_world, &cone_dir_model, orient);
vm_vec_rotate(&cone_dir_screen, &cone_dir_world, &Eye_matrix);
cone_dir_screen.xyz.z = -cone_dir_screen.xyz.z;
light_add_cone(&world_pnt, &cone_dir_screen, gpo->cone_angle, gpo->cone_inner_angle, gpo->dualcone, 1.0f, w * gpo->radius_multi, 1, pulse * gpo->light_color.xyz.x + (1.0f-pulse) * gpo->light_mix_color.xyz.x, pulse * gpo->light_color.xyz.y + (1.0f-pulse) * gpo->light_mix_color.xyz.y, pulse * gpo->light_color.xyz.z + (1.0f-pulse) * gpo->light_mix_color.xyz.z, -1);
light_add_cone(&world_pnt, &cone_dir_world, gpo->cone_angle, gpo->cone_inner_angle, gpo->dualcone, 1.0f, w * gpo->radius_multi, 1, pulse * gpo->light_color.xyz.x + (1.0f-pulse) * gpo->light_mix_color.xyz.x, pulse * gpo->light_color.xyz.y + (1.0f-pulse) * gpo->light_mix_color.xyz.y, pulse * gpo->light_color.xyz.z + (1.0f-pulse) * gpo->light_mix_color.xyz.z, -1);
} else {
light_add_point(&world_pnt, 1.0f, w * gpo->radius_multi, 1, pulse * gpo->light_color.xyz.x + (1.0f-pulse) * gpo->light_mix_color.xyz.x, pulse * gpo->light_color.xyz.y + (1.0f-pulse) * gpo->light_mix_color.xyz.y, pulse * gpo->light_color.xyz.z + (1.0f-pulse) * gpo->light_mix_color.xyz.z, -1);
}
@@ -2012,7 +2012,6 @@ void model_queue_render_thrusters(model_render_params *interp, polymodel *pm, in
int n_q = 0;
size_t k;
vec3d norm, norm2, fvec, pnt, npnt;
thruster_bank *bank = NULL;
vertex p;
bool do_render = false;
@@ -2031,7 +2030,7 @@ void model_queue_render_thrusters(model_render_params *interp, polymodel *pm, in
// get an initial count to figure out how man geo batchers we need allocated
for (i = 0; i < pm->n_thrusters; i++ ) {
bank = &pm->thrusters[i];
const auto bank = &pm->thrusters[i];
n_q += bank->num_points;
}
@@ -2073,10 +2072,10 @@ void model_queue_render_thrusters(model_render_params *interp, polymodel *pm, in
vec3d submodel_static_offset; // The associated submodel's static offset in the ship's frame of reference
bool submodel_rotation = false;
bank = &pm->thrusters[i];
const auto bank = &pm->thrusters[i];
// don't draw this thruster if the engine is destroyed or just not on
if ( !model_should_render_engine_glow(objnum, bank->obj_num) )
if (!model_should_render_engine_glow(objnum, bank->obj_num))
continue;
// If bank is attached to a submodel, prepare to account for rotations
@@ -2085,18 +2084,21 @@ void model_queue_render_thrusters(model_render_params *interp, polymodel *pm, in
// set the the necessary submodel instance info needed here. The second
// condition is thus a hack to disable the feature while in the lab, and
// can be removed if the lab is re-structured accordingly. -zookeeper
if ( bank->submodel_num > -1 && pm->submodel[bank->submodel_num].can_move && (gameseq_get_state_idx(GS_STATE_LAB) == -1) ) {
model_find_submodel_offset(&submodel_static_offset, Ship_info[shipp->ship_info_index].model_num, bank->submodel_num);
if (bank->submodel_num > -1 && pm->submodel[bank->submodel_num].can_move &&
(gameseq_get_state_idx(GS_STATE_LAB) == -1)) {
model_find_submodel_offset(&submodel_static_offset,
Ship_info[shipp->ship_info_index].model_num,
bank->submodel_num);
submodel_rotation = true;
}
for (j = 0; j < bank->num_points; j++) {
Assert( bank->points != NULL );
Assert(bank->points != NULL);
float d, D;
vec3d tempv;
glow_point *gpt = &bank->points[j];
glow_point* gpt = &bank->points[j];
vec3d loc_offset = gpt->pnt;
vec3d loc_norm = gpt->norm;
vec3d world_pnt;
@@ -2147,21 +2149,21 @@ void model_queue_render_thrusters(model_render_params *interp, polymodel *pm, in
D = d = vm_vec_dot(&tempv, &world_norm);
// ADAM: Min throttle draws rad*MIN_SCALE, max uses max.
#define NOISE_SCALE 0.5f
#define MIN_SCALE 3.4f
#define MAX_SCALE 4.7f
const auto NOISE_SCALE = 0.5f;
const auto MIN_SCALE = 3.4f;
const auto MAX_SCALE = 4.7f;
float magnitude;
vec3d scale_vec = { { { 1.0f, 0.0f, 0.0f } } };
vec3d scale_vec = {{{1.0f, 0.0f, 0.0f}}};
// normalize banks, in case of incredibly big normals
if ( !IS_VEC_NULL_SQ_SAFE(&world_norm) )
if (!IS_VEC_NULL_SQ_SAFE(&world_norm))
vm_vec_copy_normalize(&scale_vec, &world_norm);
// adjust for thrust
(scale_vec.xyz.x *= thruster_info.length.xyz.x) -= 0.1f;
(scale_vec.xyz.y *= thruster_info.length.xyz.y) -= 0.1f;
(scale_vec.xyz.z *= thruster_info.length.xyz.z) -= 0.1f;
(scale_vec.xyz.z *= thruster_info.length.xyz.z) -= 0.1f;
// get magnitude, which we will use as the scaling reference
magnitude = vm_vec_normalize(&scale_vec);
@@ -2289,9 +2291,9 @@ void model_queue_render_thrusters(model_render_params *interp, polymodel *pm, in
// Where the particles emit from
pe.pos = npnt;
// Initial velocity of all the particles
pe.vel = Objects[shipp->objnum].phys_info.desired_vel;
pe.vel = Objects[shipp->objnum].phys_info.desired_vel;
pe.min_vel = v * 0.75f;
pe.max_vel = v * 1.25f;
pe.max_vel = v * 1.25f;
// What normal the particle emit around
pe.normal = orient->vec.fvec;
vm_vec_negate(&pe.normal);
@@ -2300,16 +2302,37 @@ void model_queue_render_thrusters(model_render_params *interp, polymodel *pm, in
pe.num_low = tp->n_low;
// Highest number of particles to create
pe.num_high = tp->n_high;
pe.min_rad = gpt->radius * tp->min_rad;
pe.max_rad = gpt->radius * tp->max_rad;
pe.min_rad = gpt->radius * tp->min_rad;
pe.max_rad = gpt->radius * tp->max_rad;
// How close they stick to that normal 0=on normal, 1=180, 2=360 degree
pe.normal_variance = tp->variance;
pe.min_life = 0.0f;
pe.max_life = 1.0f;
pe.min_life = 0.0f;
pe.max_life = 1.0f;
particle::emit( &pe, particle::PARTICLE_BITMAP, tp->thruster_bitmap.first_frame);
particle::emit(&pe, particle::PARTICLE_BITMAP, tp->thruster_bitmap.first_frame);
}
}
// vec3d debug_pnt = world_pnt + (10.f * magnitude) * world_norm;
// graphics::debug::line_3d(&world_pnt, &debug_pnt, &Color_red);
//
// graphics::debug::text_3d(&debug_pnt, &Color_white, std::to_string(magnitude));
const auto lightRadius = std::max(1.0f, gpt->radius) * 250.f;
const auto outerAngle = cosf(50.0f / 180.0f * PI);
const auto innerAngle = cosf(25.0f / 180.0f * PI);
light_add_cone(&world_pnt,
&world_norm,
outerAngle,
innerAngle,
false,
lightRadius,
lightRadius,
magnitude,
0.1f,
0.1f,
0.9f,
-1);
}
}
}
+2 -8
View File
@@ -36,18 +36,12 @@
/**
* Start the frame. Pass non-zero to enable zbuffering
*/
#define g3_start_frame(zbuffer_flag) g3_start_frame_func(zbuffer_flag, __FILE__, __LINE__ )
/**
* Use the g3_start_frame macro instead of calling this directly.
*/
extern void g3_start_frame_func(int zbuffer_flag, const char *filename, int lineno);
extern void g3_start_frame(int zbuffer_flag);
/**
* End the frame
*/
#define g3_end_frame() g3_end_frame_func( __FILE__, __LINE__ )
extern void g3_end_frame_func(const char *filename, int lineno);
extern void g3_end_frame();
/**
* Currently in frame?
+2 -2
View File
@@ -72,7 +72,7 @@ int g3_in_frame()
* Start the frame
* Pass true for zbuffer_flag to turn on zbuffering
*/
void g3_start_frame_func(int zbuffer_flag, const char * /*filename*/, int /*lineno*/)
void g3_start_frame(int zbuffer_flag)
{
float s;
int width, height;
@@ -113,7 +113,7 @@ void g3_start_frame_func(int zbuffer_flag, const char * /*filename*/, int /*lin
/**
* This doesn't do anything, but is here for completeness
*/
void g3_end_frame_func(const char * /*filename*/, int /*lineno*/)
void g3_end_frame()
{
G3_count--;
Assert( G3_count == 0 );
+2
View File
@@ -349,6 +349,8 @@ add_file_folder("GlobalIncs\\\\Toolchain"
add_file_folder("Graphics"
graphics/2d.cpp
graphics/2d.h
graphics/debug.cpp
graphics/debug.h
graphics/decal_draw_list.cpp
graphics/decal_draw_list.h
graphics/grbatch.cpp