Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Portions of this file are copyright Rebirth contributors and licensed as
  3.  * described in COPYING.txt.
  4.  * Portions of this file are copyright Parallax Software and licensed
  5.  * according to the Parallax license below.
  6.  * See COPYING.txt for license details.
  7.  
  8. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  9. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  10. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  11. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  12. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  13. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  14. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  15. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  16. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  17. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  18. */
  19.  
  20. /*
  21.  *
  22.  * Header file for 3d library
  23.  * except for functions implemented in interp.c
  24.  *
  25.  */
  26.  
  27. #pragma once
  28.  
  29. #include <cstdint>
  30. #include "dxxsconf.h"
  31. #include "dsx-ns.h"
  32. #include "maths.h"
  33. #include "vecmat.h" //the vector/matrix library
  34. #include "fwd-gr.h"
  35. #include <array>
  36.  
  37. #if DXX_USE_EDITOR
  38. namespace dcx {
  39. extern int g3d_interp_outline;      //if on, polygon models outlined in white
  40. }
  41. #endif
  42.  
  43. //Structure for storing u,v,light values.  This structure doesn't have a
  44. //prefix because it was defined somewhere else before it was moved here
  45. struct g3s_uvl {
  46.         fix u,v,l;
  47. };
  48.  
  49. //Structure for storing light color. Also uses l of g3s-uvl to add/compute mono (white) light
  50. struct g3s_lrgb {
  51.         fix r,g,b;
  52. };
  53.  
  54. //Stucture to store clipping codes in a word
  55. struct g3s_codes {
  56.         //or is low byte, and is high byte
  57.         uint8_t uor = 0, uand = 0xff;
  58. };
  59.  
  60. //flags for point structure
  61. constexpr std::integral_constant<uint8_t, 1> PF_PROJECTED{};            //has been projected, so sx,sy valid
  62. constexpr std::integral_constant<uint8_t, 2> PF_OVERFLOW{};             //can't project
  63. #if !DXX_USE_OGL
  64. constexpr std::integral_constant<uint8_t, 4> PF_TEMP_POINT{};   //created during clip
  65. constexpr std::integral_constant<uint8_t, 8> PF_UVS{};                  //has uv values set
  66. constexpr std::integral_constant<uint8_t, 16> PF_LS{};                  //has lighting values set
  67. #endif
  68.  
  69. //clipping codes flags
  70.  
  71. constexpr std::integral_constant<uint8_t, 1> CC_OFF_LEFT{};
  72. constexpr std::integral_constant<uint8_t, 2> CC_OFF_RIGHT{};
  73. constexpr std::integral_constant<uint8_t, 4> CC_OFF_BOT{};
  74. constexpr std::integral_constant<uint8_t, 8> CC_OFF_TOP{};
  75. constexpr std::integral_constant<uint8_t, 0x80> CC_BEHIND{};
  76.  
  77. //Used to store rotated points for mines.  Has frame count to indictate
  78. //if rotated, and flag to indicate if projected.
  79. struct g3s_point {
  80.         vms_vector p3_vec;  //x,y,z of rotated point
  81. #if !DXX_USE_OGL
  82.         fix p3_u,p3_v,p3_l; //u,v,l coords
  83. #endif
  84.         fix p3_sx,p3_sy;    //screen x&y
  85.         ubyte p3_codes;     //clipping codes
  86.         ubyte p3_flags;     //projected?
  87.         uint16_t p3_last_generation;
  88. };
  89.  
  90. //macros to reference x,y,z elements of a 3d point
  91. #define p3_x p3_vec.x
  92. #define p3_y p3_vec.y
  93. #define p3_z p3_vec.z
  94.  
  95. #ifdef __cplusplus
  96. //Functions in library
  97.  
  98. //Frame setup functions:
  99.  
  100. namespace dcx {
  101.  
  102. #if DXX_USE_OGL
  103. typedef const g3s_point cg3s_point;
  104. #else
  105. typedef g3s_point cg3s_point;
  106. #endif
  107.  
  108. //start the frame
  109. void g3_start_frame(grs_canvas &);
  110.  
  111. //set view from x,y,z, viewer matrix, and zoom.  Must call one of g3_set_view_*()
  112. void g3_set_view_matrix(const vms_vector &view_pos,const vms_matrix &view_matrix,fix zoom);
  113.  
  114. //end the frame
  115. #if DXX_USE_OGL
  116. #define g3_end_frame() ogl_end_frame()
  117. #else
  118. #define g3_end_frame()
  119. #endif
  120.  
  121. //Instancing
  122.  
  123. //instance at specified point with specified orientation
  124. void g3_start_instance_matrix();
  125. void g3_start_instance_matrix(const vms_vector &pos, const vms_matrix &orient);
  126.  
  127. //instance at specified point with specified orientation
  128. void g3_start_instance_angles(const vms_vector &pos, const vms_angvec &angles);
  129.  
  130. //pops the old context
  131. void g3_done_instance();
  132.  
  133. //Misc utility functions:
  134.  
  135. //returns true if a plane is facing the viewer. takes the unrotated surface
  136. //normal of the plane, and a point on it.  The normal need not be normalized
  137. bool g3_check_normal_facing(const vms_vector &v,const vms_vector &norm);
  138.  
  139. }
  140.  
  141. //Point definition and rotation functions:
  142.  
  143. //specify the arrays refered to by the 'pointlist' parms in the following
  144. //functions.  I'm not sure if we will keep this function, but I need
  145. //it now.
  146. //void g3_set_points(g3s_point *points,vms_vector *vecs);
  147.  
  148. //returns codes_and & codes_or of a list of points numbers
  149. g3s_codes g3_check_codes(int nv,g3s_point **pointlist);
  150.  
  151. namespace dcx {
  152.  
  153. //rotates a point. returns codes.  does not check if already rotated
  154. ubyte g3_rotate_point(g3s_point &dest,const vms_vector &src);
  155. static inline g3s_point g3_rotate_point(const vms_vector &src) __attribute_warn_unused_result;
  156. static inline g3s_point g3_rotate_point(const vms_vector &src)
  157. {
  158.         g3s_point dest;
  159.         return g3_rotate_point(dest, src), dest;
  160. }
  161.  
  162. //projects a point
  163. void g3_project_point(g3s_point &point);
  164.  
  165. //calculate the depth of a point - returns the z coord of the rotated point
  166. fix g3_calc_point_depth(const vms_vector &pnt);
  167.  
  168. //from a 2d point, compute the vector through that point
  169. void g3_point_2_vec(vms_vector &v,short sx,short sy);
  170.  
  171. //code a point.  fills in the p3_codes field of the point, and returns the codes
  172. ubyte g3_code_point(g3s_point &point);
  173.  
  174. //delta rotation functions
  175. void g3_rotate_delta_vec(vms_vector &dest,const vms_vector &src);
  176.  
  177. ubyte g3_add_delta_vec(g3s_point &dest,const g3s_point &src,const vms_vector &deltav);
  178.  
  179. //Drawing functions:
  180.  
  181. //draw a flat-shaded face.
  182. //returns 1 if off screen, 0 if drew
  183. void _g3_draw_poly(grs_canvas &, uint_fast32_t nv, cg3s_point *const *pointlist, uint8_t color);
  184. template <std::size_t N>
  185. static inline void g3_draw_poly(grs_canvas &canvas, const uint_fast32_t nv, const std::array<cg3s_point *, N> &pointlist, const uint8_t color)
  186. {
  187.         _g3_draw_poly(canvas, nv, &pointlist[0], color);
  188. }
  189.  
  190. constexpr std::integral_constant<std::size_t, 64> MAX_POINTS_PER_POLY{};
  191.  
  192. //draw a texture-mapped face.
  193. //returns 1 if off screen, 0 if drew
  194. void _g3_draw_tmap(grs_canvas &canvas, unsigned nv, cg3s_point *const *pointlist, const g3s_uvl *uvl_list, const g3s_lrgb *light_rgb, grs_bitmap &bm);
  195.  
  196. template <std::size_t N>
  197. static inline void g3_draw_tmap(grs_canvas &canvas, unsigned nv, const std::array<cg3s_point *, N> &pointlist, const std::array<g3s_uvl, N> &uvl_list, const std::array<g3s_lrgb, N> &light_rgb, grs_bitmap &bm)
  198. {
  199.         static_assert(N <= MAX_POINTS_PER_POLY, "too many points in tmap");
  200. #ifdef DXX_CONSTANT_TRUE
  201.         if (DXX_CONSTANT_TRUE(nv > N))
  202.                 DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_tmap_overread, "reading beyond array");
  203. #endif
  204.         if (nv > N)
  205.                 return;
  206.         _g3_draw_tmap(canvas, nv, &pointlist[0], &uvl_list[0], &light_rgb[0], bm);
  207. }
  208.  
  209. template <std::size_t N>
  210. static inline void g3_draw_tmap(grs_canvas &canvas, const std::array<cg3s_point *, N> &pointlist, const std::array<g3s_uvl, N> &uvl_list, const std::array<g3s_lrgb, N> &light_rgb, grs_bitmap &bm)
  211. {
  212.         g3_draw_tmap(canvas, N, pointlist, uvl_list, light_rgb, bm);
  213. }
  214.  
  215. //draw a sortof sphere - i.e., the 2d radius is proportional to the 3d
  216. //radius, but not to the distance from the eye
  217. void g3_draw_sphere(grs_canvas &, cg3s_point &pnt, fix rad, uint8_t color);
  218.  
  219. //@@//return ligting value for a point
  220. //@@fix g3_compute_lighting_value(g3s_point *rotated_point,fix normval);
  221.  
  222. //like g3_draw_poly(), but checks to see if facing.  If surface normal is
  223. //NULL, this routine must compute it, which will be slow.  It is better to
  224. //pre-compute the normal, and pass it to this function.  When the normal
  225. //is passed, this function works like g3_check_normal_facing() plus
  226. //g3_draw_poly().
  227. //returns -1 if not facing, 1 if off screen, 0 if drew
  228. bool do_facing_check(const std::array<cg3s_point *, 3> &vertlist);
  229.  
  230. //like g3_draw_poly(), but checks to see if facing.  If surface normal is
  231. //NULL, this routine must compute it, which will be slow.  It is better to
  232. //pre-compute the normal, and pass it to this function.  When the normal
  233. //is passed, this function works like g3_check_normal_facing() plus
  234. //g3_draw_poly().
  235. //returns -1 if not facing, 1 if off screen, 0 if drew
  236. static inline void g3_check_and_draw_poly(grs_canvas &canvas, const std::array<cg3s_point *, 3> &pointlist, const uint8_t color)
  237. {
  238.         if (do_facing_check(pointlist))
  239.                 g3_draw_poly(canvas, pointlist.size(), pointlist, color);
  240. }
  241.  
  242. template <std::size_t N>
  243. static inline void g3_check_and_draw_tmap(grs_canvas &canvas, unsigned nv, const std::array<cg3s_point *, N> &pointlist, const std::array<g3s_uvl, N> &uvl_list, const std::array<g3s_lrgb, N> &light_rgb, grs_bitmap &bm)
  244. {
  245.         if (do_facing_check(pointlist))
  246.                 g3_draw_tmap(canvas, nv, pointlist, uvl_list, light_rgb, bm);
  247. }
  248.  
  249. template <std::size_t N>
  250. static inline void g3_check_and_draw_tmap(grs_canvas &canvas, const std::array<cg3s_point *, N> &pointlist, const std::array<g3s_uvl, N> &uvl_list, const std::array<g3s_lrgb, N> &light_rgb, grs_bitmap &bm)
  251. {
  252.         g3_check_and_draw_tmap(canvas, N, pointlist, uvl_list, light_rgb, bm);
  253. }
  254.  
  255. //draws a line. takes two points.
  256. #if !DXX_USE_OGL
  257. struct temporary_points_t;
  258. #endif
  259.  
  260. //draw a bitmap object that is always facing you
  261. //returns 1 if off screen, 0 if drew
  262. void g3_draw_rod_tmap(grs_canvas &, grs_bitmap &bitmap, const g3s_point &bot_point, fix bot_width, const g3s_point &top_point, fix top_width, g3s_lrgb light);
  263.  
  264. //draws a bitmap with the specified 3d width & height
  265. //returns 1 if off screen, 0 if drew
  266. void g3_draw_bitmap(grs_canvas &, const vms_vector &pos, fix width, fix height, grs_bitmap &bm);
  267.  
  268. //specifies 2d drawing routines to use instead of defaults.  Passing
  269. //NULL for either or both restores defaults
  270. #if DXX_USE_OGL
  271. enum class tmap_drawer_constant : uint_fast8_t
  272. {
  273.         polygon,
  274.         flat,
  275. };
  276.  
  277. #define draw_tmap tmap_drawer_constant::polygon
  278. #define draw_tmap_flat tmap_drawer_constant::flat
  279.  
  280. class tmap_drawer_type
  281. {
  282.         tmap_drawer_constant type;
  283. public:
  284.         constexpr tmap_drawer_type(tmap_drawer_constant t) : type(t)
  285.         {
  286.         }
  287.         bool operator==(tmap_drawer_constant t) const
  288.                 {
  289.                         return type == t;
  290.                 }
  291.         bool operator!=(tmap_drawer_constant t) const
  292.                 {
  293.                         return type != t;
  294.                 }
  295. };
  296. #define g3_draw_line(C,P0,P1,c) g3_draw_line(P0,P1,c)
  297. #else
  298. void g3_draw_line(grs_canvas &, cg3s_point &p0, cg3s_point &p1, uint8_t color, temporary_points_t &);
  299. constexpr std::integral_constant<std::size_t, 100> MAX_POINTS_IN_POLY{};
  300.  
  301. using tmap_drawer_type = void (*)(grs_canvas &, const grs_bitmap &bm, uint_fast32_t nv, const g3s_point *const *vertlist);
  302.  
  303. //      This is the gr_upoly-like interface to the texture mapper which uses texture-mapper compatible
  304. //      (ie, avoids cracking) edge/delta computation.
  305. void gr_upoly_tmap(grs_canvas &, uint_fast32_t nverts, const std::array<fix, MAX_POINTS_IN_POLY * 2> &vert, uint8_t color);
  306. #endif
  307. void g3_draw_line(grs_canvas &canvas, cg3s_point &p0, cg3s_point &p1, uint8_t color);
  308.  
  309. void g3_set_special_render(tmap_drawer_type tmap_drawer);
  310.  
  311. extern tmap_drawer_type tmap_drawer_ptr;
  312.  
  313. }
  314.  
  315. #endif
  316.