Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 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