1 /* 2 * Copyright (C) Volition, Inc. 1999. All rights reserved. 3 * 4 * All source code herein is the property of Volition, Inc. You may not sell 5 * or otherwise commercially exploit the source or things you created based on the 6 * source. 7 * 8 */ 9 10 11 #ifndef _3D_H 12 #define _3D_H 13 14 #include "math/vecmat.h" 15 #include "graphics/tmapper.h" 16 #include "graphics/2d.h" 17 #include "graphics/grbatch.h" 18 #include "camera/camera.h" 19 20 //flags for point structure 21 #define PF_PROJECTED 1 //has been projected, so sx,sy valid 22 #define PF_OVERFLOW 2 //can't project 23 #define PF_TEMP_POINT 4 //created during clip 24 25 //clipping codes flags 26 #define CC_OFF_LEFT 1 27 #define CC_OFF_RIGHT 2 28 #define CC_OFF_BOT 4 29 #define CC_OFF_TOP 8 30 #define CC_OFF_USER 16 31 #define CC_BEHIND 0x80 32 33 // Combo! 34 #define CC_OFF (CC_OFF_LEFT | CC_OFF_RIGHT | CC_OFF_BOT | CC_OFF_TOP | CC_OFF_USER | CC_BEHIND) 35 36 /** 37 * Start the frame. Pass non-zero to enable zbuffering 38 */ 39 #define g3_start_frame(zbuffer_flag) g3_start_frame_func(zbuffer_flag, __FILE__, __LINE__ ) 40 41 /** 42 * Use the g3_start_frame macro instead of calling this directly. 43 */ 44 extern void g3_start_frame_func(int zbuffer_flag, char * filename, int lineno); 45 46 /** 47 * End the frame 48 */ 49 #define g3_end_frame() g3_end_frame_func( __FILE__, __LINE__ ) 50 extern void g3_end_frame_func(char *filename, int lineno); 51 52 /** 53 * Currently in frame? 54 */ 55 extern int g3_in_frame(); 56 57 /** 58 * Set view from x,y,z & p,b,h, zoom. Must call one of g3_set_view_*() 59 */ 60 void g3_set_view_angles(vec3d *view_pos,angles *view_orient,float zoom); 61 62 /** 63 * Set view from camera 64 */ 65 void g3_set_view(camera *cam); 66 67 /** 68 * Set view from x,y,z, viewer matrix, and zoom. Must call one of g3_set_view_*() 69 */ 70 void g3_set_view_matrix(vec3d *view_pos,matrix *view_matrix,float zoom); 71 72 // Never set these! 73 extern matrix View_matrix; // The matrix to convert local coordinates to screen 74 extern vec3d View_position; // The offset to convert local coordinates to screen 75 76 extern matrix Light_matrix; // Used to rotate world points into current local coordinates 77 extern vec3d Light_base; // Used to rotate world points into current local coordinates 78 79 extern matrix Eye_matrix; // Where the viewer's eye is pointing in World coordinates 80 extern vec3d Eye_position; // Where the viewer's eye is at in World coordinates 81 extern float Eye_fov; // What the viewer's FOV is 82 83 extern vec3d Object_position; 84 extern matrix Object_matrix; // Where the opject is pointing in World coordinates 85 86 extern float Proj_fov; // Projection matrix fov (for HT&L) 87 88 /** 89 * Draw a horizon 90 */ 91 void g3_draw_horizon(int sky_color,int ground_color); 92 93 /** 94 * Draws a line representing the horizon 95 */ 96 void g3_draw_horizon_line(); 97 98 /** 99 * Get vectors that are edge of horizon 100 */ 101 int g3_compute_sky_polygon(float *points_2d,vec3d *vecs); 102 103 /** 104 * Instance at specified point with specified orientation 105 */ 106 void g3_start_instance_matrix(vec3d *pos,matrix *orient, bool set_api = true); 107 108 /** 109 * Instance at specified point with specified orientation 110 */ 111 void g3_start_instance_angles(vec3d *pos,angles *orient); 112 113 /** 114 * Pops the old context 115 */ 116 void g3_done_instance(bool set_api = false); 117 118 /** 119 * Get current field of view. Fills in angle for x & y 120 */ 121 void g3_get_FOV(float *fov_x,float *fov_y); 122 123 /** 124 * Get zoom. 125 * 126 * For a given window size, return the zoom which will achieve 127 * the given FOV along the given axis. 128 */ 129 float g3_get_zoom(char axis,float fov,int window_width,int window_height); 130 131 /** 132 * Returns the normalized, unscaled view vectors 133 */ 134 void g3_get_view_vectors(vec3d *forward,vec3d *up,vec3d *right); 135 136 /** 137 * Returns true if a plane is facing the viewer. 138 * 139 * Takes the unrotated surface normal of the plane, and a point on it. The normal need not be normalized 140 */ 141 int g3_check_normal_facing(vec3d *v,vec3d *norm); 142 143 /** 144 * Returns codes_and & codes_or of a list of points numbers 145 */ 146 ccodes g3_check_codes(int nv,vertex **pointlist); 147 148 /** 149 * Rotates a point. returns codes. does not check if already rotated 150 */ 151 ubyte g3_rotate_vertex(vertex *dest,vec3d *src); 152 153 /** 154 * Same as above, only ignores the current instancing 155 */ 156 ubyte g3_rotate_vertex_popped(vertex *dest,vec3d *src); 157 158 /** 159 * Use this for stars, etc 160 */ 161 ubyte g3_rotate_faraway_vertex(vertex *dest,vec3d *src); 162 163 /** 164 * Projects a point 165 */ 166 int g3_project_vertex(vertex *point); 167 168 /** 169 * Projects a vector 170 */ 171 ubyte g3_project_vector(vec3d *p, float *sx, float *sy ); 172 173 /** 174 * Rotates a point. 175 * @return Returns codes. 176 */ 177 ubyte g3_rotate_vector(vec3d *dest,vec3d *src); 178 179 /** 180 * Codes a vector. 181 * @return Returns the codes of a point. 182 */ 183 ubyte g3_code_vector(vec3d * p); 184 185 /** 186 * Calculate the depth of a point - returns the z coord of the rotated point 187 */ 188 float g3_calc_point_depth(vec3d *pnt); 189 190 /** 191 * From a 2d point, compute the vector through that point 192 */ 193 void g3_point_to_vec(vec3d *v,int sx,int sy); 194 195 /** 196 * From a 2d point, compute the vector through that point. 197 * 198 * This can be called outside of a g3_start_frame/g3_end_frame 199 * pair as long g3_start_frame was previously called. 200 */ 201 void g3_point_to_vec_delayed(vec3d *v,int sx,int sy); 202 203 /* 204 * Code a point. Fills in the p3_codes field of the point, and returns the codes 205 */ 206 ubyte g3_code_vertex(vertex *point); 207 208 vec3d *g3_rotate_delta_x(vec3d *dest,float dx); 209 vec3d *g3_rotate_delta_y(vec3d *dest,float dy); 210 vec3d *g3_rotate_delta_z(vec3d *dest,float dz); 211 vec3d *g3_rotate_delta_vec(vec3d *dest,vec3d *src); 212 ubyte g3_add_delta_vec(vertex *dest,vertex *src,vec3d *deltav); 213 214 /** 215 * Draw a polygon. 216 * 217 * Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture. 218 * @return Returns 1 if off screen, 0 if drawn 219 */ 220 int g3_draw_poly(int nv,vertex **pointlist,uint tmap_flags); 221 222 int g3_draw_polygon(vec3d *pos, matrix *ori, float width, float height, int tmap_flags = TMAP_FLAG_TEXTURED); 223 int g3_draw_polygon(vec3d *pos, vec3d *norm, float width, float height, int tmap_flags = TMAP_FLAG_TEXTURED); 224 225 /** 226 * Draw a polygon. 227 * 228 * Same as g3_draw_poly, but it bashes sw to a constant value 229 * for all vertexes. Needs to be done after clipping to get them all. 230 * 231 * Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture. 232 * @return Returns 1 if off screen, 0 if drawn 233 */ 234 int g3_draw_poly_constant_sw(int nv,vertex **pointlist,uint tmap_flags, float constant_sw); 235 236 /** 237 * Like g3_draw_poly(), but checks to see if facing. 238 * 239 * If surface normal is NULL, this routine must compute it, which will be slow. 240 * It is better to pre-compute the normal, and pass it to this function. 241 * When the normal is passed, this function works like g3_check_normal_facing() plus g3_draw_poly(). 242 * 243 * Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture. 244 * @return Returns -1 if not facing, 1 if off screen, 0 if drawn 245 */ 246 int g3_draw_poly_if_facing(int nv,vertex **pointlist,uint tmap_flags,vec3d *norm,vec3d *pnt); 247 248 /** 249 * Draws a line. 250 * 251 * @param p0 First point 252 * @param p1 Second point 253 */ 254 int g3_draw_line(vertex *p0,vertex *p1); 255 256 /** 257 * Draws a polygon always facing the viewer. 258 * Compute the corners of a rod. fills in vertbuf. 259 * Verts has any needs uv's or l's or can be NULL if none needed. 260 */ 261 int g3_draw_rod(vec3d *p0,float width1,vec3d *p1,float width2, vertex * verts, uint tmap_flags); 262 263 /** 264 * Draws a bitmap with the specified 3d width & height 265 * 266 * Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture. 267 * @return Returns 1 if off screen, 0 if drawn 268 * 269 * If bitmap is not square, rad will be the 3d size of the smallest dimension. 270 * orient flips the bitmap in some way. Pass 0 for normal or else pass a 271 * random nuber between 0 and 7, inclusive. 272 */ 273 int g3_draw_bitmap(vertex *pos,int orient, float radius, uint tmap_flags, float depth = 0.0f); 274 275 /** 276 * Get bitmap dims onscreen as if g3_draw_bitmap() had been called 277 */ 278 int g3_get_bitmap_dims(int bitmap, vertex *pos, float radius, int *x, int *y, int *w, int *h, int *size); 279 280 /** 281 * Draw a sortof sphere - i.e., the 2d radius is proportional to the 3d 282 * radius, but not to the distance from the eye. Uses the current 2d color. 283 */ 284 int g3_draw_sphere(vertex *pnt,float rad); 285 286 /** 287 * Same as g3_draw_sphere, but you pass a vector and this rotates 288 * and projects it and then call g3_draw_sphere. 289 */ 290 int g3_draw_sphere_ez(vec3d *pnt,float rad); 291 292 /** 293 * Draw a laser shaped 3d looking thing. 294 * 295 * If max_len is > 1.0, then this caps the length to be no longer than max_len pixels 296 */ 297 float g3_draw_laser(vec3d *headp, float head_width, vec3d *tailp, float tail_width, uint tmap_flags = TMAP_FLAG_TEXTURED, float max_len = 0.0f ); 298 299 /** 300 * Draw a laser shaped 3d looking thing using vertex coloring (useful for things like colored laser glows) 301 * 302 * If max_len is > 1.0, then this caps the length to be no longer than max_len pixels 303 */ 304 float g3_draw_laser_rgb(vec3d *headp, float head_width, vec3d *tailp, float tail_width, int r, int g, int b, uint tmap_flags = TMAP_FLAG_TEXTURED | TMAP_FLAG_RGB, float max_len = 0.0f ); 305 306 /** 307 * Draw a bitmap that is always facing, but rotates. 308 * 309 * If bitmap is not square, rad will be the 3d size of the smallest dimension. 310 */ 311 int g3_draw_rotated_bitmap(vertex *pnt,float angle, float radius, uint tmap_flags, float depth = 0.0f); 312 313 /** 314 * Draw a perspective bitmap based on angles and radius 315 */ 316 int g3_draw_perspective_bitmap(angles *a, float scale_x, float scale_y, int div_x, int div_y, uint tmap_flags); 317 318 /** 319 * Draw a 2D shield icon w/ 6 points 320 */ 321 void g3_draw_2d_shield_icon(const coord2d coords[6], const int r, const int g, const int b, const int a); 322 323 /** 324 * Draw a 2D rectangle 325 */ 326 void g3_draw_2d_rect(int x, int y, int w, int h, int r, int g, int b, int a); 327 328 /** 329 * Draw a 2d bitmap on a poly 330 */ 331 int g3_draw_2d_poly_bitmap(float x, float y, float w, float h, uint additional_tmap_flags = 0); 332 333 /** 334 * Enables clipping with an arbritary plane. 335 * 336 * This will be on until g3_stop_clip_plane is called or until next frame. 337 * The points passed should be relative to the instance. Probably 338 * that means world coordinates. 339 * 340 * This works like any other clip plane... if this is enabled and you 341 * rotate a point, the CC_OFF_USER bit will be set in the clipping codes. 342 * It is completely handled by most g3_draw primitives, except maybe lines. 343 * 344 * As far as performance, when enabled, it will slow down each point 345 * rotation (or g3_code_vertex call) by a vec3d subtraction and dot 346 * product. It won't slow anything down for polys that are completely 347 * clipped on or off by the plane, and will slow each clipped polygon by 348 * not much more than any other clipping we do. 349 */ 350 void g3_start_user_clip_plane( vec3d *plane_point, vec3d *plane_normal ); 351 352 /** 353 * Stops arbritary plane clipping 354 */ 355 void g3_stop_user_clip_plane(); 356 357 ubyte g3_transfer_vertex(vertex *dest, vec3d *src); 358 359 int g3_draw_2d_poly_bitmap_list(bitmap_2d_list* b_list, int n_bm, uint additional_tmap_flags); 360 int g3_draw_2d_poly_bitmap_rect_list(bitmap_rect_list* b_list, int n_bm, uint additional_tmap_flags); 361 362 /** 363 * Draw a line in HTL mode without having to go through the rotate/project stuff 364 */ 365 void g3_draw_htl_line(vec3d *start, vec3d *end); 366 367 /** 368 * Draw a sphere mode without having to go through the rotate/project stuff 369 */ 370 void g3_draw_htl_sphere(vec3d *position, float radius); 371 372 /** 373 * Flash ball 374 * 375 * A neat looking ball of rays that move around and look all energetic and stuff 376 */ 377 struct flash_beam{ 378 vertex start; 379 vertex end; 380 float width; 381 }; 382 383 class flash_ball{ 384 flash_beam *ray; 385 vec3d center; 386 int n_rays; 387 static geometry_batcher batcher; 388 void parse_bsp(int offset, ubyte *bsp_data); 389 void defpoint(int off, ubyte *bsp_data); 390 391 public: 392 flash_ball(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) ray(NULL)393 :ray(NULL),n_rays(0) 394 {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()395 ~flash_ball(){if(ray)vm_free(ray);} 396 397 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); 398 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); 399 void render(float rad, float intinsity, float life); 400 }; 401 #endif 402