1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
|
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#ifndef _3D_H
#define _3D_H
#include "camera/camera.h"
#include "graphics/2d.h"
#include "graphics/grbatch.h"
#include "graphics/tmapper.h"
#include "math/vecmat.h"
//flags for point structure
#define PF_PROJECTED 1 //has been projected, so sx,sy valid
#define PF_OVERFLOW 2 //can't project
#define PF_TEMP_POINT 4 //created during clip
//clipping codes flags
#define CC_OFF_LEFT 1
#define CC_OFF_RIGHT 2
#define CC_OFF_BOT 4
#define CC_OFF_TOP 8
#define CC_OFF_USER 16
#define CC_BEHIND 0x80
// Combo!
#define CC_OFF (CC_OFF_LEFT | CC_OFF_RIGHT | CC_OFF_BOT | CC_OFF_TOP | CC_OFF_USER | CC_BEHIND)
/**
* 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);
/**
* End the frame
*/
#define g3_end_frame() g3_end_frame_func( __FILE__, __LINE__ )
extern void g3_end_frame_func(const char *filename, int lineno);
/**
* Currently in frame?
*/
extern int g3_in_frame();
constexpr float PROJ_FOV_FACTOR = 1.39626348f;
extern fov_t Proj_fov; // Projection matrix fov (for HT&L)
/**
* Sets the Proj_fov from the specified zoom value
*/
void g3_set_fov(fov_t zoom);
float g3_get_hfov(const fov_t& fov);
/**
* Set view from camera
*/
void g3_set_view(camera *cam);
/**
* Set view from x,y,z, viewer matrix, and zoom. Must call one of g3_set_view_*()
*/
void g3_set_view_matrix(const vec3d *view_pos, const matrix *view_matrix, fov_t zoom);
// Never set these!
extern matrix View_matrix; // The matrix to convert local coordinates to screen
extern vec3d View_position; // The offset to convert local coordinates to screen
extern matrix Light_matrix; // Used to rotate world points into current local coordinates
extern vec3d Light_base; // Used to rotate world points into current local coordinates
extern matrix Eye_matrix; // Where the viewer's eye is pointing in World coordinates
extern vec3d Eye_position; // Where the viewer's eye is at in World coordinates
extern fov_t Eye_fov; // What the viewer's FOV is
extern vec3d Object_position;
extern matrix Object_matrix; // Where the opject is pointing in World coordinates
/**
* Draws a line representing the horizon
*/
void g3_draw_horizon_line();
/**
* Instance at specified point with specified orientation
*/
void g3_start_instance_matrix(const vec3d *pos, const matrix *orient, bool set_api = true);
/**
* Instance at specified point with specified transform.
*/
void g3_start_instance_matrix(const matrix4 *transform, bool set_api = true);
/**
* Instance at specified point with specified orientation
*/
void g3_start_instance_angles(const vec3d *pos, const angles *orient);
/**
* Pops the old context
*/
void g3_done_instance(bool set_api = false);
/**
* Returns true if a plane is facing the viewer.
*
* Takes the unrotated surface normal of the plane, and a point on it. The normal need not be normalized
*/
int g3_check_normal_facing(const vec3d *v, const vec3d *norm);
/**
* Rotates a point. returns codes. does not check if already rotated
*/
ubyte g3_rotate_vertex(vertex *dest, const vec3d *src);
/**
* Use this for stars, etc
*/
ubyte g3_rotate_faraway_vertex(vertex *dest, const vec3d *src);
/**
* Projects a point
*/
int g3_project_vertex(vertex *point);
/**
* Projects a vector
*/
ubyte g3_project_vector(const vec3d *p, float *sx, float *sy );
/**
* Rotates a point.
* @return Returns codes.
*/
ubyte g3_rotate_vector(vec3d *dest, const vec3d *src);
/**
* Codes a vector.
* @return Returns the codes of a point.
*/
ubyte g3_code_vector(const vec3d * p);
/**
* Calculate the depth of a point - returns the z coord of the rotated point
*/
float g3_calc_point_depth(const vec3d *pnt);
/**
* From a 2d point, compute the vector through that point
*/
void g3_point_to_vec(vec3d *v,int sx,int sy);
/**
* From a 2d point, compute the vector through that point.
*
* This can be called outside of a g3_start_frame/g3_end_frame
* pair as long g3_start_frame was previously called.
*/
void g3_point_to_vec_delayed(vec3d *v,int sx,int sy);
/*
* Code a point. Fills in the p3_codes field of the point, and returns the codes
*/
ubyte g3_code_vertex(vertex *point);
vec3d *g3_rotate_delta_vec(vec3d *dest,vec3d *src);
/**
* Draws a line.
*
* @param p0 First point
* @param p1 Second point
*/
int g3_draw_line(vertex *p0, vertex *p1);
/**
* Get bitmap dims onscreen as if g3_draw_bitmap() had been called
*/
int g3_get_bitmap_dims(int bitmap, vertex *pos, float radius, int *x, int *y, int *w, int *h, int *size);
/**
* Draw a sortof sphere - i.e., the 2d radius is proportional to the 3d
* radius, but not to the distance from the eye. Uses the current 2d color.
*/
int g3_draw_sphere(vertex *pnt, float rad);
/**
* Same as g3_draw_sphere, but you pass a vector and this rotates
* and projects it and then call g3_draw_sphere.
*/
int g3_draw_sphere_ez(const vec3d *pnt, float rad);
ubyte g3_transfer_vertex(vertex *dest, const vec3d *src);
/**
* Draw a line in HTL mode without having to go through the rotate/project stuff
*/
void g3_draw_htl_line(const vec3d *start, const vec3d *end);
/**
* Draw a sphere mode without having to go through the rotate/project stuff
*/
void g3_draw_htl_sphere(color* clr,
const vec3d* position,
float radius,
gr_alpha_blend alpha_blend_mode,
gr_zbuffer_type zbuffer_mode);
void g3_draw_htl_sphere(color* clr, const vec3d* position, float radius);
void g3_draw_htl_sphere(const vec3d* position, float radius);
void g3_render_primitives(material* mat, vertex* verts, int n_verts, primitive_type prim_type, bool orthographic = false);
void g3_render_primitives_textured(material* mat, vertex* verts, int n_verts, primitive_type prim_type, bool orthographic = false);
void g3_render_primitives_colored(material* mat, vertex* verts, int n_verts, primitive_type prim_type, bool orthographic = false);
void g3_render_primitives_colored_textured(material* mat, vertex* verts, int n_verts, primitive_type prim_type, bool orthographic = false);
void g3_render_rod(const color *clr, int num_points, const vec3d *pvecs, float width);
void g3_render_laser_2d(material *mat_params, vec3d *headp, float head_width, vec3d *tailp, float tail_width, float max_len);
void g3_render_rect_screen_aligned_rotated(material *mat_params, vertex *pnt, float angle, float rad);
void g3_render_rect_screen_aligned(material *mat_params, vertex *pnt, int orient, float rad, float depth = 0.0f);
void g3_render_rect_screen_aligned_2d(material *mat_params, vertex *pnt, int orient, float rad);
void g3_render_rect_oriented(material* mat_info, vec3d *pos, matrix *ori, float width, float height);
void g3_render_rect_oriented(material* mat_info, vec3d *pos, vec3d *norm, float width, float height);
void g3_render_line_3d(color *clr, bool depth_testing, const vec3d *start, const vec3d *end);
void g3_render_line_3d(bool depth_testing, const vec3d *start, const vec3d *end);
void g3_render_sphere(color *clr, vec3d* position, float radius);
void g3_render_sphere(vec3d* position, float radius);
void g3_render_shield_icon(color *clr, coord2d coords[6], int resize_mode = GR_RESIZE_FULL);
void g3_render_shield_icon(coord2d coords[6], int resize_mode = GR_RESIZE_FULL);
typedef struct horz_pt {
float x, y;
int edge;
} horz_pt;
/**
* Flash ball
*
* A neat looking ball of rays that move around and look all energetic and stuff
*/
struct flash_beam{
vertex start;
vertex end;
float width;
};
class flash_ball{
flash_beam *ray;
vec3d center;
uint n_rays;
void parse_bsp(int offset, ubyte *bsp_data);
void defpoint(int off, ubyte *bsp_data);
public:
flash_ball(int number, float min_ray_width, float max_ray_width = 0, const vec3d* dir = &vmd_zero_vector, const 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)
:ray(NULL),n_rays(0)
{
initialize(number, min_ray_width, max_ray_width, dir, pcenter, outer, inner, max_r, max_g, max_b, min_r, min_g, min_b);
}
~flash_ball()
{
if (ray)
vm_free(ray);
}
void initialize(uint number, float min_ray_width, float max_ray_width = 0, const vec3d* dir = &vmd_zero_vector, const 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, const vec3d* dir = &vmd_zero_vector, const 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(int texture, float rad, float intinsity, float life);
};
#endif
|