dxx-rebirth/common/include/3d.h

263 lines
8.9 KiB
C
Raw Normal View History

2006-03-20 16:43:15 +00:00
/*
2014-06-01 17:55:23 +00:00
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING.txt.
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below.
* See COPYING.txt for license details.
2006-03-20 16:43:15 +00:00
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
2006-03-20 16:43:15 +00:00
COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
*/
2006-03-20 16:43:15 +00:00
/*
*
* Header file for 3d library
* except for functions implemented in interp.c
2006-03-20 16:43:15 +00:00
*
*/
#ifndef _3D_H
#define _3D_H
2014-08-16 18:14:11 +00:00
#include "dxxsconf.h"
2012-07-01 02:54:33 +00:00
#include "maths.h"
#include "vecmat.h" //the vector/matrix library
2006-03-20 16:43:15 +00:00
#include "gr.h"
extern int g3d_interp_outline; //if on, polygon models outlined in white
2006-03-20 16:43:15 +00:00
extern short highest_texture_num;
//Structure for storing u,v,light values. This structure doesn't have a
//prefix because it was defined somewhere else before it was moved here
struct g3s_uvl {
2006-03-20 16:43:15 +00:00
fix u,v,l;
};
2006-03-20 16:43:15 +00:00
//Structure for storing light color. Also uses l of g3s-uvl to add/compute mono (white) light
struct g3s_lrgb {
fix r,g,b;
};
2006-03-20 16:43:15 +00:00
//Stucture to store clipping codes in a word
struct g3s_codes {
ubyte uor,uand; //or is low byte, and is high byte
2014-08-16 18:14:11 +00:00
constexpr g3s_codes() :
uor(0), uand(0xff)
{
}
};
2006-03-20 16:43:15 +00:00
//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
#define PF_UVS 8 //has uv values set
#define PF_LS 16 //has lighting values set
2006-03-20 16:43:15 +00:00
//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_BEHIND 0x80
2006-03-20 16:43:15 +00:00
//Used to store rotated points for mines. Has frame count to indictate
//if rotated, and flag to indicate if projected.
struct g3s_point {
vms_vector p3_vec; //x,y,z of rotated point
fix p3_u,p3_v,p3_l; //u,v,l coords
fix p3_sx,p3_sy; //screen x&y
ubyte p3_codes; //clipping codes
ubyte p3_flags; //projected?
uint16_t p3_last_generation;
};
2006-03-20 16:43:15 +00:00
//macros to reference x,y,z elements of a 3d point
#define p3_x p3_vec.x
#define p3_y p3_vec.y
#define p3_z p3_vec.z
//An object, such as a robot
struct g3s_object {
2006-03-20 16:43:15 +00:00
vms_vector o3_pos; //location of this object
vms_angvec o3_orient; //orientation of this object
int o3_nverts; //number of points in the object
int o3_nfaces; //number of faces in the object
//this will be filled in later
};
2006-03-20 16:43:15 +00:00
#ifdef __cplusplus
2012-11-11 00:14:30 +00:00
extern grs_point blob_vertices[4];
2006-03-20 16:43:15 +00:00
//Functions in library
//Frame setup functions:
//start the frame
void g3_start_frame(void);
//set view from x,y,z, viewer matrix, and zoom. Must call one of g3_set_view_*()
2014-10-26 22:01:00 +00:00
void g3_set_view_matrix(const vms_vector &view_pos,const vms_matrix &view_matrix,fix zoom);
2006-03-20 16:43:15 +00:00
//end the frame
void g3_end_frame(void);
//draw a horizon
void g3_draw_horizon(int sky_color,int ground_color);
//Instancing
//instance at specified point with specified orientation
2014-10-02 03:02:35 +00:00
void g3_start_instance_matrix(const vms_vector &pos,const vms_matrix *orient);
2006-03-20 16:43:15 +00:00
//instance at specified point with specified orientation
void g3_start_instance_angles(const vms_vector &pos,const vms_angvec *angles);
2006-03-20 16:43:15 +00:00
//pops the old context
void g3_done_instance();
//Misc utility functions:
//get zoom. For a given window size, return the zoom which will achieve
//the given FOV along the given axis.
fix g3_get_zoom(char axis,fixang fov,short window_width,short window_height);
//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
2014-10-02 03:02:35 +00:00
bool g3_check_normal_facing(const vms_vector &v,const vms_vector &norm);
2006-03-20 16:43:15 +00:00
//Point definition and rotation functions:
//specify the arrays refered to by the 'pointlist' parms in the following
//functions. I'm not sure if we will keep this function, but I need
//it now.
//void g3_set_points(g3s_point *points,vms_vector *vecs);
//returns codes_and & codes_or of a list of points numbers
g3s_codes g3_check_codes(int nv,g3s_point **pointlist);
//rotates a point. returns codes. does not check if already rotated
2014-10-02 03:02:35 +00:00
ubyte g3_rotate_point(g3s_point &dest,const vms_vector &src);
2006-03-20 16:43:15 +00:00
//projects a point
2014-11-13 03:21:33 +00:00
void g3_project_point(g3s_point &point);
2006-03-20 16:43:15 +00:00
//calculate the depth of a point - returns the z coord of the rotated point
2014-10-26 22:01:04 +00:00
fix g3_calc_point_depth(const vms_vector &pnt);
2006-03-20 16:43:15 +00:00
//from a 2d point, compute the vector through that point
2014-10-02 03:02:36 +00:00
void g3_point_2_vec(vms_vector &v,short sx,short sy);
2006-03-20 16:43:15 +00:00
//code a point. fills in the p3_codes field of the point, and returns the codes
2014-11-13 03:16:17 +00:00
ubyte g3_code_point(g3s_point &point);
2006-03-20 16:43:15 +00:00
//delta rotation functions
2014-10-02 03:02:36 +00:00
vms_vector &g3_rotate_delta_vec(vms_vector &dest,const vms_vector &src);
2014-10-02 03:02:36 +00:00
ubyte g3_add_delta_vec(g3s_point &dest,const g3s_point &src,const vms_vector &deltav);
2006-03-20 16:43:15 +00:00
//Drawing functions:
//draw a flat-shaded face.
//returns 1 if off screen, 0 if drew
bool g3_draw_poly(int nv,g3s_point **pointlist);
2006-03-20 16:43:15 +00:00
2014-09-04 03:02:21 +00:00
static const std::size_t MAX_POINTS_PER_POLY = 25;
2006-03-20 16:43:15 +00:00
//draw a texture-mapped face.
//returns 1 if off screen, 0 if drew
2014-09-04 03:02:21 +00:00
void _g3_draw_tmap(unsigned nv, g3s_point **pointlist, const g3s_uvl *uvl_list, const g3s_lrgb *light_rgb, grs_bitmap *bm);
template <std::size_t N>
static inline void g3_draw_tmap(unsigned nv, g3s_point **pointlist, const array<g3s_uvl, N> &uvl_list, const array<g3s_lrgb, N> &light_rgb, grs_bitmap *bm)
{
static_assert(N <= MAX_POINTS_PER_POLY, "too many points in tmap");
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
if (__builtin_constant_p(nv > N) && nv > N)
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_tmap_overread, "reading beyond array");
#endif
_g3_draw_tmap(nv, pointlist, &uvl_list[0], &light_rgb[0], bm);
}
template <std::size_t N>
static inline void g3_draw_tmap(g3s_point **pointlist, const array<g3s_uvl, N> &uvl_list, const array<g3s_lrgb, N> &light_rgb, grs_bitmap *bm)
{
g3_draw_tmap(N, pointlist, uvl_list, light_rgb, bm);
}
2006-03-20 16:43:15 +00:00
//draw a sortof sphere - i.e., the 2d radius is proportional to the 3d
//radius, but not to the distance from the eye
2014-11-13 03:22:49 +00:00
int g3_draw_sphere(g3s_point &pnt,fix rad);
2006-03-20 16:43:15 +00:00
//@@//return ligting value for a point
//@@fix g3_compute_lighting_value(g3s_point *rotated_point,fix normval);
//like g3_draw_poly(), but checks to see if facing. If surface normal is
//NULL, this routine must compute it, which will be slow. It is better to
//pre-compute the normal, and pass it to this function. When the normal
//is passed, this function works like g3_check_normal_facing() plus
//g3_draw_poly().
//returns -1 if not facing, 1 if off screen, 0 if drew
2014-08-27 03:16:51 +00:00
bool do_facing_check(g3s_point **vertlist);
//like g3_draw_poly(), but checks to see if facing. If surface normal is
//NULL, this routine must compute it, which will be slow. It is better to
//pre-compute the normal, and pass it to this function. When the normal
//is passed, this function works like g3_check_normal_facing() plus
//g3_draw_poly().
//returns -1 if not facing, 1 if off screen, 0 if drew
static inline void g3_check_and_draw_poly(int nv, g3s_point **pointlist)
{
if (do_facing_check(pointlist))
g3_draw_poly(nv,pointlist);
}
2014-09-04 03:02:21 +00:00
template <std::size_t N>
static inline void g3_check_and_draw_tmap(unsigned nv, g3s_point **pointlist, const array<g3s_uvl, N> &uvl_list, const array<g3s_lrgb, N> &light_rgb, grs_bitmap *bm)
2014-08-27 03:16:51 +00:00
{
if (do_facing_check(pointlist))
g3_draw_tmap(nv,pointlist,uvl_list,light_rgb,bm);
}
2006-03-20 16:43:15 +00:00
2014-09-04 03:02:21 +00:00
template <std::size_t N>
static inline void g3_check_and_draw_tmap(g3s_point **pointlist, const array<g3s_uvl, N> &uvl_list, const array<g3s_lrgb, N> &light_rgb, grs_bitmap *bm)
{
g3_check_and_draw_tmap(N, pointlist, uvl_list, light_rgb, bm);
}
2006-03-20 16:43:15 +00:00
//draws a line. takes two points.
2014-11-13 03:19:52 +00:00
bool g3_draw_line(g3s_point &p0,g3s_point &p1);
2006-03-20 16:43:15 +00:00
//draw a bitmap object that is always facing you
//returns 1 if off screen, 0 if drew
void g3_draw_rod_tmap(grs_bitmap *bitmap,g3s_point *bot_point,fix bot_width,g3s_point *top_point,fix top_width,g3s_lrgb light);
2006-03-20 16:43:15 +00:00
//draws a bitmap with the specified 3d width & height
2006-03-20 16:43:15 +00:00
//returns 1 if off screen, 0 if drew
2014-10-02 03:02:35 +00:00
bool g3_draw_bitmap(const vms_vector &pos,fix width,fix height,grs_bitmap *bm);
2006-03-20 16:43:15 +00:00
//specifies 2d drawing routines to use instead of defaults. Passing
//NULL for either or both restores defaults
typedef void (*tmap_drawer_type)(grs_bitmap *bm,int nv,g3s_point **vertlist);
typedef void (*flat_drawer_type)(int nv,const int *vertlist);
typedef int (*line_drawer_type)(fix x0,fix y0,fix x1,fix y1);
void g3_set_special_render(tmap_drawer_type tmap_drawer);
2006-03-20 16:43:15 +00:00
2012-11-11 00:14:30 +00:00
extern tmap_drawer_type tmap_drawer_ptr;
#endif
#endif