1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "controller.hh"
|
---|
10 | #include "map.hh"
|
---|
11 | #include "window/win_evt.hh"
|
---|
12 | #include "time/profile.hh"
|
---|
13 | #include "menu/menu.hh"
|
---|
14 | #include "menu/textitem.hh"
|
---|
15 | #include "window/style.hh"
|
---|
16 | #include "time/time.hh"
|
---|
17 | #include "resources.hh"
|
---|
18 | #include "input.hh"
|
---|
19 | #include "mess_id.hh"
|
---|
20 | #include "sound_man.hh"
|
---|
21 | #include "g1_speed.hh"
|
---|
22 | #include "remove_man.hh"
|
---|
23 | #include "image/color.hh"
|
---|
24 | #include "light.hh"
|
---|
25 | #include "statistics.hh"
|
---|
26 | #include "r1_api.hh"
|
---|
27 | #include "r1_clip.hh"
|
---|
28 | #include "math/random.hh"
|
---|
29 | #include "math/pi.hh"
|
---|
30 | #include "math/angle.hh"
|
---|
31 | #include "math/trig.hh"
|
---|
32 | #include "g1_render.hh"
|
---|
33 | #include "tile.hh"
|
---|
34 | #include "g1_tint.hh"
|
---|
35 | #include "time/profile.hh"
|
---|
36 | #include "g1_texture_id.hh"
|
---|
37 | #include "g1_tint.hh"
|
---|
38 | #include "objs/map_piece.hh"
|
---|
39 | #include "objs/stank.hh"
|
---|
40 | #include "lisp/lisp.hh"
|
---|
41 | #include "map_vert.hh"
|
---|
42 | #include "loaders/load.hh"
|
---|
43 | #include "r1_font.hh"
|
---|
44 |
|
---|
45 | static i4_profile_class pf_render_object_transform("::render_object (transform)"),
|
---|
46 | pf_render_object_light("::render_object (light)"),
|
---|
47 | pf_render_object_pack("::render_object (project/pack)"),
|
---|
48 | pf_render_sprite("g1_render::render_sprite"),
|
---|
49 | pf_render_draw_outline("g1_render::draw_outline"),
|
---|
50 | pf_post_draw_quads("g1_render::post_draw_quads"),
|
---|
51 | pf_add_translucent_trail("g1_render::add_trans_trail"),
|
---|
52 | pf_draw_building("g1_render::draw_building");
|
---|
53 |
|
---|
54 |
|
---|
55 |
|
---|
56 | const sw32 max_post_draw_quads = 1024;
|
---|
57 | static g1_post_draw_quad_class g1_post_draw_quads[max_post_draw_quads];
|
---|
58 | static sw32 g1_num_post_draw_quads = 0;
|
---|
59 |
|
---|
60 | const sw32 max_post_draw_verts = max_post_draw_quads*4;
|
---|
61 | static r1_vert g1_post_draw_verts[max_post_draw_verts];
|
---|
62 | static sw32 g1_num_post_draw_verts = 0;
|
---|
63 |
|
---|
64 | struct g1_post_draw_sprite_struct
|
---|
65 | {
|
---|
66 | r1_texture_handle tex;
|
---|
67 | float z;
|
---|
68 | float s1, t1, s2, t2;
|
---|
69 | float x1,y1,x2,y2;
|
---|
70 |
|
---|
71 | } g1_post_draw_sprites[G1_MAX_SPRITES];
|
---|
72 | int g1_t_post_draw_sprites=0;
|
---|
73 |
|
---|
74 |
|
---|
75 |
|
---|
76 | g1_render_class g1_render;
|
---|
77 |
|
---|
78 | //this is used for the damage/blackening effect of hurt vehicles
|
---|
79 |
|
---|
80 | static w8 charred_array[8] =
|
---|
81 | {
|
---|
82 | 8|1|128|4|32|2|64,
|
---|
83 | 8|1|128|4|32|2,
|
---|
84 | 8|1|128|4|32,
|
---|
85 | 8|1|128|4,
|
---|
86 | 8|1|128,
|
---|
87 | 8|1,
|
---|
88 | 8,
|
---|
89 | 0
|
---|
90 | };
|
---|
91 |
|
---|
92 | i4_bool g1_render_class::main_draw=i4_F;
|
---|
93 |
|
---|
94 | i4_float g1_render_class::scale_x,
|
---|
95 | g1_render_class::scale_y,
|
---|
96 | g1_render_class::ooscale_x,
|
---|
97 | g1_render_class::ooscale_y,
|
---|
98 | g1_render_class::center_x,
|
---|
99 | g1_render_class::center_y;
|
---|
100 |
|
---|
101 | sw8 g1_render_class::render_damage_level = -1;
|
---|
102 |
|
---|
103 | r1_render_api_class *g1_render_class::r_api;
|
---|
104 |
|
---|
105 |
|
---|
106 | float g1_render_class::calculate_frame_ratio()
|
---|
107 | {
|
---|
108 | if (g1_map_is_loaded())
|
---|
109 | {
|
---|
110 | i4_time_class now;
|
---|
111 | if (g1_resources.paused)
|
---|
112 | frame_ratio=1.0;
|
---|
113 | else
|
---|
114 | frame_ratio=1.0+now.milli_diff(g1_get_map()->tick_time)*G1_HZ/1000.0;
|
---|
115 |
|
---|
116 | if (frame_ratio>1)
|
---|
117 | frame_ratio=1;
|
---|
118 | }
|
---|
119 | else frame_ratio=0;
|
---|
120 |
|
---|
121 | return frame_ratio;
|
---|
122 | }
|
---|
123 |
|
---|
124 | // this is the default function for handling tinted polygons
|
---|
125 | g1_quad_class *g1_tint_modify_function(g1_quad_class *in,
|
---|
126 | g1_player_type player)
|
---|
127 | {
|
---|
128 | g1_render.r_api->set_color_tint(g1_player_tint_handles[player]);
|
---|
129 | return in;
|
---|
130 | }
|
---|
131 |
|
---|
132 | void g1_get_ambient_function(i4_transform_class *object_to_world,
|
---|
133 | i4_float &ar, i4_float &ag, i4_float &ab)
|
---|
134 | {
|
---|
135 | g1_get_map()->get_illumination_light(object_to_world->t.x,
|
---|
136 | object_to_world->t.y, ar,ag,ab);
|
---|
137 | }
|
---|
138 |
|
---|
139 |
|
---|
140 |
|
---|
141 | void fast_transform(i4_transform_class *t,const i4_3d_vector &src, r1_3d_point_class &dst)
|
---|
142 | {
|
---|
143 | #ifndef WIN32
|
---|
144 | dst.x = t->x.x*src.x + t->y.x*src.y + t->z.x*src.z + t->t.x;
|
---|
145 | dst.y = t->x.y*src.x + t->y.y*src.y + t->z.y*src.z + t->t.y;
|
---|
146 | dst.z = t->x.z*src.x + t->y.z*src.y + t->z.z*src.z + t->t.z;
|
---|
147 | #else
|
---|
148 | _asm
|
---|
149 | {
|
---|
150 | mov eax, t
|
---|
151 | mov ecx, src
|
---|
152 | mov edx, dst
|
---|
153 |
|
---|
154 | //optimized transformation: 34 cycles
|
---|
155 | //compute t->x.x*src.x, t->x.y*src.x, t->x.z*src.x
|
---|
156 | fld dword ptr [ecx+0] ;starts & ends on cycle 0
|
---|
157 | fmul dword ptr [eax+0] ;starts on cycle 1
|
---|
158 | fld dword ptr [ecx+0] ;starts & ends on cycle 2
|
---|
159 | fmul dword ptr [eax+4] ;starts on cycle 3
|
---|
160 | fld dword ptr [ecx+0] ;starts & ends on cycle 4
|
---|
161 | fmul dword ptr [eax+8] ;starts on cycle 5
|
---|
162 |
|
---|
163 | //compute t->y.x*src.y, t->y.y*src.y, t->y.z*src.y
|
---|
164 | fld dword ptr [ecx+4] ;starts & ends on cycle 6
|
---|
165 | fmul dword ptr [eax+12] ;starts on cycle 7
|
---|
166 | fld dword ptr [ecx+4] ;starts & ends on cycle 8
|
---|
167 | fmul dword ptr [eax+16] ;starts on cycle 9
|
---|
168 | fld dword ptr [ecx+4] ;starts & ends on cycle 10
|
---|
169 | fmul dword ptr [eax+20] ;starts on cycle 11
|
---|
170 |
|
---|
171 | //st0 st1 st2 st3 st4 st5
|
---|
172 | //t->y.z*src.y t->y.y*src.y t->y.x*src.y t->x.z*src.x t->x.y*src.x t->x.x*src.x
|
---|
173 |
|
---|
174 | fxch st(2) ;no cost
|
---|
175 | //st0 st1 st2 st3 st4 st5
|
---|
176 | //t->y.x*src.y t->y.y*src.y t->y.z*src.y t->x.z*src.x t->x.y*src.x t->x.x*src.x
|
---|
177 |
|
---|
178 | faddp st(5),st(0) ;starts on cycle 12
|
---|
179 | //st0 st1 st2 st3 st4
|
---|
180 | //t->y.y*src.y t->y.z*src.y t->x.z*src.x t->x.y*src.x t->x.x*src.x+
|
---|
181 | // t->y.x*src.y
|
---|
182 |
|
---|
183 | faddp st(3),st(0) ;starts on cycle 13
|
---|
184 | //st0 st1 st2 st3
|
---|
185 | //t->y.z*src.y t->x.z*src.x t->x.y*src.x+ t->x.x*src.x+
|
---|
186 | // t->y.y*src.y t->y.x*src.y
|
---|
187 |
|
---|
188 | faddp st(1),st(0) ;starts on cycle 14
|
---|
189 | //st0 st1 st2
|
---|
190 | //t->x.z*src.x+ t->x.y*src.x+ t->x.x*src.x+
|
---|
191 | //t->y.z*src.y t->y.y*src.y t->y.x*src.y
|
---|
192 |
|
---|
193 | //compute t->z.x*src.z, t->z.y*src.z, t->z.z*src.z
|
---|
194 | fld dword ptr [ecx+8] ;starts & ends on cycle 15
|
---|
195 | fmul dword ptr [eax+24] ;starts on cycle 16
|
---|
196 | fld dword ptr [ecx+8] ;starts & ends on cycle 17
|
---|
197 | fmul dword ptr [eax+28] ;starts on cycle 18
|
---|
198 | fld dword ptr [ecx+8] ;starts & ends on cycle 19
|
---|
199 | fmul dword ptr [eax+32] ;starts on cycle 20
|
---|
200 |
|
---|
201 | //st0 st1 st2 st3 st4 st5
|
---|
202 | //t->z.z*src.z t->z.y*src.z t->z.x*src.z t->x.z*src.x+ t->x.y*src.x+ t->x.x*src.x+
|
---|
203 | // t->y.z*src.y t->y.y*src.y t->y.x*src.y
|
---|
204 | fxch st(2) ;no cost
|
---|
205 |
|
---|
206 | faddp st(5),st(0) ;starts on cycle 21
|
---|
207 | //st0 st1 st2 st3 st4
|
---|
208 | //t->z.y*src.z t->z.z*src.z t->x.z*src.x+ t->x.y*src.x+ t->x.x*src.x+
|
---|
209 | // t->y.z*src.y t->y.y*src.y t->y.x*src.y+
|
---|
210 | // t->z.x*src.z
|
---|
211 |
|
---|
212 | faddp st(3),st(0) ;starts on cycle 22
|
---|
213 |
|
---|
214 | //st0 st1 st2 st3
|
---|
215 | //t->z.z*src.z t->x.z*src.x+ t->x.y*src.x+ t->x.x*src.x+
|
---|
216 | // t->y.z*src.y t->y.y*src.y+ t->y.x*src.y+
|
---|
217 | // t->z.y*src.z t->z.x*src.z
|
---|
218 |
|
---|
219 | faddp st(1),st(0) ;starts on cycle 23
|
---|
220 | //st0 st1 st2
|
---|
221 | //t->x.z*src.x+ t->x.y*src.x+ t->x.x*src.x+
|
---|
222 | //t->y.z*src.y+ t->y.y*src.y+ t->y.x*src.y+
|
---|
223 | //t->z.z*src.z t->z.y*src.z t->z.x*src.z
|
---|
224 |
|
---|
225 | fxch st(2) ;no cost
|
---|
226 | //st0 st1 st2
|
---|
227 | //t->x.x*src.x+ t->x.y*src.x+ t->x.z*src.x+
|
---|
228 | //t->y.x*src.y+ t->y.y*src.y+ t->y.z*src.y+
|
---|
229 | //t->z.x*src.z t->z.y*src.z t->z.z*src.z
|
---|
230 |
|
---|
231 | fadd dword ptr [eax+36] ;starts on cycle 24
|
---|
232 | fxch st(1) ;starts on cycle 25
|
---|
233 |
|
---|
234 | //st0 st1 st2
|
---|
235 | //t->x.y*src.x+ dest_x t->x.z*src.x+
|
---|
236 | //t->y.y*src.y+ t->y.z*src.y+
|
---|
237 | //t->z.y*src.z t->z.z*src.z
|
---|
238 |
|
---|
239 | fadd dword ptr [eax+40] ;starts on cycle 26
|
---|
240 | fxch st(2) ;no cost
|
---|
241 |
|
---|
242 | //st0 st1 st2
|
---|
243 | //t->x.z*src.x+ dest_x dest_y
|
---|
244 | //t->y.z*src.y+
|
---|
245 | //t->z.z*src.z
|
---|
246 | fadd dword ptr [eax+44] ;starts on cycle 27
|
---|
247 | fxch st(1) ;no cost
|
---|
248 |
|
---|
249 | //st0 st1 st2
|
---|
250 | //dest_x dest_z dest_y
|
---|
251 |
|
---|
252 | fstp dword ptr [edx+0] ;starts on cycle 28, ends on cycle 29
|
---|
253 | fstp dword ptr [edx+8] ;starts on cycle 30, ends on cycle 31
|
---|
254 | fstp dword ptr [edx+4] ;starts on cycle 32, ends on cycle 33
|
---|
255 | }
|
---|
256 | #endif
|
---|
257 | }
|
---|
258 |
|
---|
259 |
|
---|
260 | void g1_render_class::uninstall_font()
|
---|
261 | {
|
---|
262 | if (rendered_font)
|
---|
263 | {
|
---|
264 | delete rendered_font;
|
---|
265 | rendered_font=0;
|
---|
266 | }
|
---|
267 |
|
---|
268 |
|
---|
269 | }
|
---|
270 |
|
---|
271 | void g1_render_class::install_font()
|
---|
272 | {
|
---|
273 | uninstall_font();
|
---|
274 | i4_image_class *im=i4_load_image("bitmaps/golg_font_18.tga");
|
---|
275 | if (im)
|
---|
276 | {
|
---|
277 | rendered_font=new r1_font_class(r_api, im);
|
---|
278 | delete im;
|
---|
279 | }
|
---|
280 | }
|
---|
281 |
|
---|
282 | void g1_render_class::render_object(g1_quad_object_class *obj,
|
---|
283 | i4_transform_class *object_to_view,
|
---|
284 | i4_transform_class *object_to_world,
|
---|
285 | i4_float texture_scale,
|
---|
286 | int player_num,
|
---|
287 | sw32 current_frame,
|
---|
288 | g1_screen_box *bound_box,
|
---|
289 | w32 option_flags)
|
---|
290 | {
|
---|
291 | g1_stat_counter.increment(g1_statistics_counter_class::OBJECTS);
|
---|
292 |
|
---|
293 |
|
---|
294 | int i,j,k,num_vertices;
|
---|
295 | r1_vert t_vertices[512];
|
---|
296 | int src_quad[4];
|
---|
297 | i4_transform_class view_transform;
|
---|
298 |
|
---|
299 | num_vertices = obj->num_vertex;
|
---|
300 | r1_vert *v = t_vertices;
|
---|
301 | g1_vert_class *src_vert = obj->get_verts(0, current_frame);
|
---|
302 |
|
---|
303 | w8 ANDCODE = 0xFF;
|
---|
304 | w8 ORCODE = 0;
|
---|
305 |
|
---|
306 | g1_vert_class *src_v=src_vert;
|
---|
307 |
|
---|
308 | pf_render_object_transform.start();
|
---|
309 |
|
---|
310 | //get this vector before we warp the transform
|
---|
311 | i4_3d_vector cam_in_object_space;
|
---|
312 | object_to_view->inverse_transform(i4_3d_vector(0,0,0),cam_in_object_space);
|
---|
313 |
|
---|
314 |
|
---|
315 | view_transform.x.x = object_to_view->x.x * scale_x;
|
---|
316 | view_transform.x.y = object_to_view->x.y * scale_y;
|
---|
317 | view_transform.x.z = object_to_view->x.z;
|
---|
318 | view_transform.y.x = object_to_view->y.x * scale_x;
|
---|
319 | view_transform.y.y = object_to_view->y.y * scale_y;
|
---|
320 | view_transform.y.z = object_to_view->y.z;
|
---|
321 | view_transform.z.x = object_to_view->z.x * scale_x;
|
---|
322 | view_transform.z.y = object_to_view->z.y * scale_y;
|
---|
323 | view_transform.z.z = object_to_view->z.z;
|
---|
324 | view_transform.t.x = object_to_view->t.x * scale_x;
|
---|
325 | view_transform.t.y = object_to_view->t.y * scale_y;
|
---|
326 | view_transform.t.z = object_to_view->t.z;
|
---|
327 |
|
---|
328 | for (i=0; i<num_vertices; i++, src_v++, v++)
|
---|
329 | {
|
---|
330 | fast_transform(&view_transform,src_v->v,v->v);
|
---|
331 |
|
---|
332 | //v->v.x *= scale_x; //this is accomplished by the above matrix multiplies
|
---|
333 | //v->v.y *= scale_y;
|
---|
334 |
|
---|
335 | w8 code = r1_calc_outcode(v);
|
---|
336 | ANDCODE &= code;
|
---|
337 | ORCODE |= code;
|
---|
338 | if (!code)
|
---|
339 | {
|
---|
340 | //valid point
|
---|
341 | i4_float ooz = r1_ooz(v->v.z);
|
---|
342 |
|
---|
343 | v->px = v->v.x * ooz * center_x + center_x;
|
---|
344 | v->py = v->v.y * ooz * center_y + center_y;
|
---|
345 |
|
---|
346 |
|
---|
347 | v->w = ooz;
|
---|
348 | }
|
---|
349 | }
|
---|
350 |
|
---|
351 | pf_render_object_transform.stop();
|
---|
352 |
|
---|
353 | if (ANDCODE)
|
---|
354 | return;
|
---|
355 |
|
---|
356 | pf_render_object_light.start();
|
---|
357 |
|
---|
358 | //IMPORTANT
|
---|
359 | //we need this transform to do lighting
|
---|
360 | if (object_to_world)
|
---|
361 | {
|
---|
362 | //worldspace light vector
|
---|
363 | i4_3d_vector light = g1_lights.direction;
|
---|
364 | i4_3d_vector t_light;
|
---|
365 |
|
---|
366 | // get the ambient contribution from the map at the object's center point
|
---|
367 | i4_float ar,ag,ab;
|
---|
368 | get_ambient(object_to_world, ar,ag,ab);
|
---|
369 |
|
---|
370 | float dir_int=g1_lights.directional_intensity;
|
---|
371 |
|
---|
372 | //transform light into object space for lighting
|
---|
373 | object_to_world->inverse_transform_3x3(light,t_light);
|
---|
374 |
|
---|
375 | src_vert = obj->get_verts(0,current_frame);
|
---|
376 | v = t_vertices;
|
---|
377 |
|
---|
378 |
|
---|
379 | for (i=0; i<num_vertices; i++, src_vert, v++)
|
---|
380 | {
|
---|
381 | // i4_float reflected_intensity = 1.0;
|
---|
382 |
|
---|
383 | i4_float dot=-src_vert[i].normal.dot(t_light);
|
---|
384 | i4_float reflected_intensity = g1_lights.directional_intensity * dot;
|
---|
385 |
|
---|
386 |
|
---|
387 | if (reflected_intensity<0)
|
---|
388 | reflected_intensity=0;
|
---|
389 |
|
---|
390 | v->r = reflected_intensity * dir_int + ar; if (v->r>1.0) v->r=1.0;
|
---|
391 | v->g = reflected_intensity * dir_int + ag; if (v->g>1.0) v->g=1.0;
|
---|
392 | v->b = reflected_intensity * dir_int + ab; if (v->b>1.0) v->b=1.0;
|
---|
393 | v->a = 1.0;
|
---|
394 | }
|
---|
395 | }
|
---|
396 | else
|
---|
397 | {
|
---|
398 | v = t_vertices;
|
---|
399 | for (i=0; i<num_vertices; i++, v++)
|
---|
400 | {
|
---|
401 | v->r = v->g = v->b = 1.f;//g1_lights.ambient_intensity;
|
---|
402 | v->a = 1.0;
|
---|
403 | }
|
---|
404 | }
|
---|
405 |
|
---|
406 |
|
---|
407 | if (render_damage_level != -1)
|
---|
408 | {
|
---|
409 | //set their lighting values to 1
|
---|
410 | v = t_vertices;
|
---|
411 | for (i=0; i<num_vertices; i++, v++)
|
---|
412 | if ((1<<(i&7)) & charred_array[render_damage_level])
|
---|
413 | v->r = v->g = v->b = 0;
|
---|
414 | }
|
---|
415 |
|
---|
416 | pf_render_object_light.stop();
|
---|
417 |
|
---|
418 | pf_render_object_pack.start();
|
---|
419 | g1_quad_class *q_ptr = obj->quad, *q;
|
---|
420 | for (i=0; i<obj->num_quad; i++, q_ptr++)
|
---|
421 | {
|
---|
422 | sw32 num_poly_verts = q_ptr->num_verts();
|
---|
423 |
|
---|
424 | i4_3d_vector cam_to_pt = src_vert[q_ptr->vertex_ref[0]].v;
|
---|
425 | cam_to_pt -= cam_in_object_space;
|
---|
426 |
|
---|
427 | float dot = cam_to_pt.dot(q_ptr->normal);
|
---|
428 |
|
---|
429 | if (dot<0)
|
---|
430 | {
|
---|
431 | if (g1_tint!=G1_TINT_OFF && g1_hurt_tint==0)
|
---|
432 | {
|
---|
433 | if ((q_ptr->get_flags(g1_quad_class::TINT)||(g1_tint==G1_TINT_ALL))
|
---|
434 | && player_num!=-1)
|
---|
435 | q=tint_modify(q_ptr, player_num);
|
---|
436 | else
|
---|
437 | {
|
---|
438 | r_api->set_color_tint(0);
|
---|
439 | q=q_ptr;
|
---|
440 | }
|
---|
441 | }
|
---|
442 | else q=q_ptr;
|
---|
443 |
|
---|
444 | // copy in the texture coordinates
|
---|
445 | for (j=0; j<num_poly_verts; j++)
|
---|
446 | {
|
---|
447 | int ref=q->vertex_ref[j];
|
---|
448 | src_quad[j]=ref;
|
---|
449 |
|
---|
450 | v = &t_vertices[ref];
|
---|
451 | v->s = q->u[j];
|
---|
452 | v->t = q->v[j];
|
---|
453 | }
|
---|
454 |
|
---|
455 |
|
---|
456 | if (ORCODE==0)
|
---|
457 | {
|
---|
458 | float nearest_w = 0;
|
---|
459 |
|
---|
460 | if (bound_box)
|
---|
461 | {
|
---|
462 | for (j=0; j<num_poly_verts; j++)
|
---|
463 | {
|
---|
464 | r1_vert *temp_vert = &t_vertices[q->vertex_ref[j]];
|
---|
465 |
|
---|
466 | float ooz = temp_vert->w;
|
---|
467 |
|
---|
468 | if (ooz > nearest_w)
|
---|
469 | nearest_w=ooz;
|
---|
470 |
|
---|
471 | if (temp_vert->px < bound_box->x1) bound_box->x1 = temp_vert->px;
|
---|
472 | if (temp_vert->px > bound_box->x2) bound_box->x2 = temp_vert->px;
|
---|
473 |
|
---|
474 | if (temp_vert->py < bound_box->y1) bound_box->y1 = temp_vert->py;
|
---|
475 | if (temp_vert->py > bound_box->y2) bound_box->y2 = temp_vert->py;
|
---|
476 |
|
---|
477 | if (temp_vert->v.z > bound_box->z2) bound_box->z2 = temp_vert->v.z;
|
---|
478 |
|
---|
479 | if (temp_vert->v.z < bound_box->z1)
|
---|
480 | {
|
---|
481 | bound_box->z1 = temp_vert->v.z;
|
---|
482 | bound_box->w = ooz;
|
---|
483 | }
|
---|
484 | }
|
---|
485 | }
|
---|
486 | else
|
---|
487 | {
|
---|
488 | for (j=0; j<num_poly_verts; j++)
|
---|
489 | {
|
---|
490 | r1_vert *temp_vert = &t_vertices[q->vertex_ref[j]];
|
---|
491 |
|
---|
492 | float ooz = temp_vert->w;
|
---|
493 |
|
---|
494 | if (ooz > nearest_w)
|
---|
495 | nearest_w=ooz;
|
---|
496 | }
|
---|
497 | }
|
---|
498 |
|
---|
499 | i4_float twidth = nearest_w * q->texture_scale * texture_scale * center_x * 2;
|
---|
500 |
|
---|
501 | r_api->use_texture(q->material_ref, i4_f_to_i(twidth), current_frame);
|
---|
502 |
|
---|
503 | g1_stat_counter.increment(g1_statistics_counter_class::OBJECT_POLYS);
|
---|
504 | g1_stat_counter.increment(g1_statistics_counter_class::TOTAL_POLYS);
|
---|
505 | r_api->render_poly(num_poly_verts,t_vertices,q->vertex_ref);
|
---|
506 | }
|
---|
507 | else
|
---|
508 | {
|
---|
509 | r1_vert temp_buf_1[64];
|
---|
510 | r1_vert temp_buf_2[64];
|
---|
511 | r1_vert *clipped_poly;
|
---|
512 |
|
---|
513 | clipped_poly = r_api->clip_poly(&num_poly_verts,
|
---|
514 | t_vertices,
|
---|
515 | q->vertex_ref,
|
---|
516 | temp_buf_1,
|
---|
517 | temp_buf_2,
|
---|
518 | R1_CLIP_NO_CALC_OUTCODE
|
---|
519 | );
|
---|
520 |
|
---|
521 |
|
---|
522 | if (clipped_poly && num_poly_verts>=3)
|
---|
523 | {
|
---|
524 | float nearest_w = 0;
|
---|
525 |
|
---|
526 | if (!bound_box)
|
---|
527 | {
|
---|
528 | r1_vert *temp_vert = clipped_poly;
|
---|
529 |
|
---|
530 | for (j=0; j<num_poly_verts; j++, temp_vert++)
|
---|
531 | {
|
---|
532 | i4_float ooz = r1_ooz(temp_vert->v.z);
|
---|
533 |
|
---|
534 | temp_vert->w = ooz;
|
---|
535 | temp_vert->px = temp_vert->v.x * ooz * center_x + center_x;
|
---|
536 | temp_vert->py = temp_vert->v.y * ooz * center_y + center_y;
|
---|
537 |
|
---|
538 | if (ooz > nearest_w)
|
---|
539 | nearest_w=ooz;
|
---|
540 | }
|
---|
541 | }
|
---|
542 | else
|
---|
543 | {
|
---|
544 | r1_vert *temp_vert = clipped_poly;
|
---|
545 |
|
---|
546 | for (j=0; j<num_poly_verts; j++,temp_vert++)
|
---|
547 | {
|
---|
548 | float ooz = r1_ooz(temp_vert->v.z);
|
---|
549 |
|
---|
550 | temp_vert->w = ooz;
|
---|
551 | temp_vert->px = temp_vert->v.x * ooz * center_x + center_x;
|
---|
552 | temp_vert->py = temp_vert->v.y * ooz * center_y + center_y;
|
---|
553 |
|
---|
554 | if (ooz > nearest_w)
|
---|
555 | nearest_w=ooz;
|
---|
556 |
|
---|
557 | if (temp_vert->px < bound_box->x1) bound_box->x1 = temp_vert->px;
|
---|
558 | if (temp_vert->px > bound_box->x2) bound_box->x2 = temp_vert->px;
|
---|
559 |
|
---|
560 | if (temp_vert->py < bound_box->y1) bound_box->y1 = temp_vert->py;
|
---|
561 | if (temp_vert->py > bound_box->y2) bound_box->y2 = temp_vert->py;
|
---|
562 |
|
---|
563 | if (temp_vert->v.z > bound_box->z2) bound_box->z2 = temp_vert->v.z;
|
---|
564 |
|
---|
565 | if (temp_vert->v.z < bound_box->z1)
|
---|
566 | {
|
---|
567 | bound_box->z1 = temp_vert->v.z;
|
---|
568 | bound_box->w = ooz;
|
---|
569 | }
|
---|
570 | }
|
---|
571 | }
|
---|
572 |
|
---|
573 | i4_float twidth = nearest_w * q->texture_scale * texture_scale * center_x * 2;
|
---|
574 | r_api->use_texture(q->material_ref, i4_f_to_i(twidth), current_frame);
|
---|
575 | r_api->render_poly(num_poly_verts,clipped_poly);
|
---|
576 |
|
---|
577 | g1_stat_counter.increment(g1_statistics_counter_class::OBJECT_POLYS);
|
---|
578 | g1_stat_counter.increment(g1_statistics_counter_class::TOTAL_POLYS);
|
---|
579 | }
|
---|
580 | }
|
---|
581 | }
|
---|
582 | }
|
---|
583 |
|
---|
584 | if (g1_tint!=G1_TINT_OFF && g1_hurt_tint==0)
|
---|
585 | r_api->set_color_tint(0);
|
---|
586 |
|
---|
587 | pf_render_object_pack.stop();
|
---|
588 | }
|
---|
589 |
|
---|
590 | void g1_render_class::render_object_polys(g1_quad_object_class *obj,
|
---|
591 | i4_transform_class *object_to_view,
|
---|
592 | sw32 current_frame)
|
---|
593 | {
|
---|
594 | int i,j,k,num_vertices;
|
---|
595 | r1_vert t_vertices[512];
|
---|
596 | int src_quad[4];
|
---|
597 | i4_transform_class view_transform;
|
---|
598 |
|
---|
599 | num_vertices = obj->num_vertex;
|
---|
600 | r1_vert *v = t_vertices;
|
---|
601 | g1_vert_class *src_vert = obj->get_verts(0, current_frame);
|
---|
602 |
|
---|
603 | w8 ANDCODE = 0xFF;
|
---|
604 | w8 ORCODE = 0;
|
---|
605 |
|
---|
606 | g1_vert_class *src_v=src_vert;
|
---|
607 |
|
---|
608 | pf_render_object_transform.start();
|
---|
609 |
|
---|
610 | view_transform.x.x = object_to_view->x.x * scale_x;
|
---|
611 | view_transform.x.y = object_to_view->x.y * scale_y;
|
---|
612 | view_transform.x.z = object_to_view->x.z;
|
---|
613 | view_transform.y.x = object_to_view->y.x * scale_x;
|
---|
614 | view_transform.y.y = object_to_view->y.y * scale_y;
|
---|
615 | view_transform.y.z = object_to_view->y.z;
|
---|
616 | view_transform.z.x = object_to_view->z.x * scale_x;
|
---|
617 | view_transform.z.y = object_to_view->z.y * scale_y;
|
---|
618 | view_transform.z.z = object_to_view->z.z;
|
---|
619 | view_transform.t.x = object_to_view->t.x * scale_x;
|
---|
620 | view_transform.t.y = object_to_view->t.y * scale_y;
|
---|
621 | view_transform.t.z = object_to_view->t.z;
|
---|
622 |
|
---|
623 | i4_float adjuster = -0.01f;
|
---|
624 |
|
---|
625 | for (i=0; i<num_vertices; i++, src_v++, v++)
|
---|
626 | {
|
---|
627 | fast_transform(&view_transform,src_v->v,v->v);
|
---|
628 |
|
---|
629 | //v->v.x *= scale_x; //this is accomplished by the above matrix multiplies
|
---|
630 | //v->v.y *= scale_y;
|
---|
631 |
|
---|
632 | w8 code = r1_calc_outcode(v);
|
---|
633 | ANDCODE &= code;
|
---|
634 | ORCODE |= code;
|
---|
635 | if (!code)
|
---|
636 | {
|
---|
637 | //valid point
|
---|
638 | i4_float ooz = r1_ooz(v->v.z);
|
---|
639 | i4_float ooz_adjusted = r1_ooz(v->v.z + adjuster);
|
---|
640 |
|
---|
641 | v->px = v->v.x * ooz * center_x + center_x;
|
---|
642 | v->py = v->v.y * ooz * center_y + center_y;
|
---|
643 |
|
---|
644 | v->w = ooz_adjusted;
|
---|
645 |
|
---|
646 | v->a = v->r = v->g = v->b = 1.f;
|
---|
647 | }
|
---|
648 | }
|
---|
649 |
|
---|
650 | pf_render_object_transform.stop();
|
---|
651 |
|
---|
652 | if (ANDCODE)
|
---|
653 | return;
|
---|
654 |
|
---|
655 | pf_render_object_pack.start();
|
---|
656 |
|
---|
657 | g1_quad_class *q_ptr = obj->quad;
|
---|
658 |
|
---|
659 | for (i=0; i<obj->num_quad; i++, q_ptr++)
|
---|
660 | {
|
---|
661 | sw32 num_poly_verts = q_ptr->num_verts();
|
---|
662 |
|
---|
663 | if (ORCODE==0)
|
---|
664 | {
|
---|
665 | r_api->render_poly(num_poly_verts,t_vertices,q_ptr->vertex_ref);
|
---|
666 | }
|
---|
667 | else
|
---|
668 | {
|
---|
669 | r1_vert temp_buf_1[64];
|
---|
670 | r1_vert temp_buf_2[64];
|
---|
671 | r1_vert *clipped_poly;
|
---|
672 |
|
---|
673 | clipped_poly = r_api->clip_poly(&num_poly_verts,
|
---|
674 | t_vertices,
|
---|
675 | q_ptr->vertex_ref,
|
---|
676 | temp_buf_1,
|
---|
677 | temp_buf_2,
|
---|
678 | R1_CLIP_NO_CALC_OUTCODE
|
---|
679 | );
|
---|
680 |
|
---|
681 | if (clipped_poly && num_poly_verts>=3)
|
---|
682 | {
|
---|
683 | r1_vert *temp_vert = clipped_poly;
|
---|
684 |
|
---|
685 | for (j=0; j<num_poly_verts; j++, temp_vert++)
|
---|
686 | {
|
---|
687 | float ooz = r1_ooz(temp_vert->v.z);
|
---|
688 | float ooz_adjusted = r1_ooz(temp_vert->v.z + adjuster);
|
---|
689 |
|
---|
690 | temp_vert->px = temp_vert->v.x * ooz * center_x + center_x;
|
---|
691 | temp_vert->py = temp_vert->v.y * ooz * center_y + center_y;
|
---|
692 |
|
---|
693 | temp_vert->w = ooz_adjusted;
|
---|
694 | }
|
---|
695 |
|
---|
696 | r_api->render_poly(num_poly_verts,clipped_poly);
|
---|
697 | }
|
---|
698 | }
|
---|
699 | }
|
---|
700 |
|
---|
701 | pf_render_object_pack.stop();
|
---|
702 | }
|
---|
703 |
|
---|
704 | void g1_render_class::render_3d_line(const i4_3d_point_class &p1,
|
---|
705 | const i4_3d_point_class &p2,
|
---|
706 | i4_color color1,
|
---|
707 | i4_color color2,
|
---|
708 | i4_transform_class *t,
|
---|
709 | i4_bool draw_in_front_of_everything)
|
---|
710 | {
|
---|
711 | r1_vert v[2];
|
---|
712 |
|
---|
713 | project_point(p1, v[0], t);
|
---|
714 | project_point(p2, v[1], t);
|
---|
715 |
|
---|
716 | if (draw_in_front_of_everything)
|
---|
717 | {
|
---|
718 | v[0].v.z=g1_near_z_range();
|
---|
719 | v[1].v.z=g1_near_z_range();
|
---|
720 |
|
---|
721 | float ooz = r1_ooz(g1_near_z_range());
|
---|
722 |
|
---|
723 | v[0].w = ooz;
|
---|
724 | v[1].w = ooz;
|
---|
725 | }
|
---|
726 |
|
---|
727 | v[0].r=g1_table_0_255_to_0_1[(color1&0xff0000)>>16];
|
---|
728 | v[0].g=g1_table_0_255_to_0_1[(color1&0xff00)>>8];
|
---|
729 | v[0].b=g1_table_0_255_to_0_1[(color1&0xff)>>0];
|
---|
730 |
|
---|
731 | v[1].r=g1_table_0_255_to_0_1[(color2&0xff0000)>>16];
|
---|
732 | v[1].g=g1_table_0_255_to_0_1[(color2&0xff00)>>8];
|
---|
733 | v[1].b=g1_table_0_255_to_0_1[(color2&0xff)>>0];
|
---|
734 |
|
---|
735 | r_api->set_shading_mode(R1_COLORED_SHADING);
|
---|
736 | r_api->set_alpha_mode(R1_ALPHA_DISABLED);
|
---|
737 | r_api->disable_texture();
|
---|
738 |
|
---|
739 | r1_clip_render_lines(1, v, center_x, center_y, r_api);
|
---|
740 | r_api->set_constant_color(0xffffff);
|
---|
741 | }
|
---|
742 |
|
---|
743 | void g1_draw_vert_line(float x, float y1, float y2, r1_vert *v)
|
---|
744 | {
|
---|
745 | r1_vert *v1=v, *v2=v+1;
|
---|
746 | v1->px=x; v2->px=x;
|
---|
747 | v1->py=y1; v2->py=y2;
|
---|
748 | g1_render.r_api->render_lines(1, v);
|
---|
749 | }
|
---|
750 |
|
---|
751 |
|
---|
752 |
|
---|
753 |
|
---|
754 | void g1_draw_horz_line(float y, float x1, float x2, r1_vert *v)
|
---|
755 |
|
---|
756 | {
|
---|
757 | r1_vert *v1=v, *v2=v+1;
|
---|
758 | v1->py=y; v2->py=y;
|
---|
759 | v1->px=x1; v2->px=x2;
|
---|
760 | g1_render.r_api->render_lines(1, v);
|
---|
761 | }
|
---|
762 |
|
---|
763 | void g1_render_class::draw_outline(g1_screen_box *box, g1_object_class *for_who)
|
---|
764 | {
|
---|
765 | pf_render_draw_outline.start();
|
---|
766 | r1_vert line_points[3];
|
---|
767 |
|
---|
768 | sw32 width = (sw32)(center_x*2);
|
---|
769 | sw32 height = (sw32)(center_y*2);
|
---|
770 |
|
---|
771 | //dunno whats up w/these.. looks like the box is ending up outside the viewport somehow
|
---|
772 |
|
---|
773 | sw32 box_x1 = i4_f_to_i(box->x1);
|
---|
774 | sw32 box_y1 = i4_f_to_i(box->y1);
|
---|
775 | sw32 box_x2 = i4_f_to_i(box->x2);
|
---|
776 | sw32 box_y2 = i4_f_to_i(box->y2);
|
---|
777 |
|
---|
778 | box_x1++;
|
---|
779 | box_y1++;
|
---|
780 | box_x2--;
|
---|
781 | box_y2--;
|
---|
782 |
|
---|
783 | if (box_x1 < 0 || box_y1 < 0 || box_x2<0 || box_y2<0)
|
---|
784 | {
|
---|
785 | pf_render_draw_outline.stop();
|
---|
786 | return;
|
---|
787 | }
|
---|
788 |
|
---|
789 | if (box_x2 > width || box_x1>width || box_y2 > height || box_y1 > height)
|
---|
790 | {
|
---|
791 | pf_render_draw_outline.stop();
|
---|
792 | return;
|
---|
793 | }
|
---|
794 |
|
---|
795 | r_api->disable_texture();
|
---|
796 |
|
---|
797 | i4_float depth = box->z1;
|
---|
798 | i4_float oodepth = box->w;
|
---|
799 |
|
---|
800 | line_points[0].v.z = depth;
|
---|
801 | line_points[0].w = oodepth;
|
---|
802 | line_points[1].v.z = depth;
|
---|
803 | line_points[1].w = oodepth;
|
---|
804 | line_points[2].v.z = depth;
|
---|
805 | line_points[2].w = oodepth;
|
---|
806 |
|
---|
807 | line_points[0].r = 0.25f;
|
---|
808 | line_points[0].g = 0.25f;
|
---|
809 | line_points[0].b = 0.f;
|
---|
810 | line_points[1].r = 1.0f;
|
---|
811 | line_points[1].g = 1.0f;
|
---|
812 | line_points[1].b = 0.f;
|
---|
813 | line_points[2].r = 0.25f;
|
---|
814 | line_points[2].g = 0.25f;
|
---|
815 |
|
---|
816 | line_points[2].b = 0.f;
|
---|
817 |
|
---|
818 | //dunno whats up w/these.. looks like the box is ending up outside the viewport somehow
|
---|
819 | box->x1 += 1;
|
---|
820 | box->y1 += 1;
|
---|
821 |
|
---|
822 |
|
---|
823 |
|
---|
824 | float width_adjust = (box_x2 - box_x1)/6;
|
---|
825 | float height_adjust = (box_y2 - box_y1)/6;
|
---|
826 |
|
---|
827 |
|
---|
828 |
|
---|
829 | line_points[0].px = box_x1;
|
---|
830 | line_points[0].py = box_y1 + height_adjust;
|
---|
831 |
|
---|
832 |
|
---|
833 |
|
---|
834 | line_points[1].px = box_x1;
|
---|
835 | line_points[1].py = box_y1;
|
---|
836 |
|
---|
837 | line_points[2].px = box_x1 + width_adjust;
|
---|
838 | line_points[2].py = box_y1;
|
---|
839 |
|
---|
840 | r_api->render_lines(2,line_points);
|
---|
841 |
|
---|
842 | g1_map_piece_class *mp;
|
---|
843 | if (for_who && (box_x1+6<=box_x2) && box_y1>=5)
|
---|
844 | {
|
---|
845 | mp=g1_map_piece_class::cast(for_who);
|
---|
846 | if (mp && mp->health>0)
|
---|
847 | {
|
---|
848 | float percent=mp->health/(float)mp->defaults->health;
|
---|
849 |
|
---|
850 | //protect against invalid health values
|
---|
851 | if (percent > 1.f) percent = 1.f;
|
---|
852 | if (percent < 0.f) percent = 0.f;
|
---|
853 |
|
---|
854 | i4_color c;
|
---|
855 |
|
---|
856 | if (percent<=0.25)
|
---|
857 | c=0xff0000; // red
|
---|
858 | if (percent<=0.5)
|
---|
859 | c=0xffff00; // yellow
|
---|
860 | else
|
---|
861 | c=0x00ff00; // green
|
---|
862 |
|
---|
863 | r_api->clear_area(box_x1, box_y1-5, box_x2, box_y1-2, 0, box->z1+0.01);
|
---|
864 |
|
---|
865 | int box_w=(box_x2-1)-(box_x1+1);
|
---|
866 | r_api->clear_area(box_x1+1, box_y1-4, box_x1+1+(int)(box_w*percent), box_y1-3, c, box->z1);
|
---|
867 | }
|
---|
868 | }
|
---|
869 |
|
---|
870 |
|
---|
871 | line_points[0].px = box_x2 - width_adjust;
|
---|
872 | line_points[0].py = box_y1;
|
---|
873 |
|
---|
874 | line_points[1].px = box_x2;
|
---|
875 | line_points[1].py = box_y1;
|
---|
876 |
|
---|
877 | line_points[2].px = box_x2;
|
---|
878 | line_points[2].py = box_y1 + height_adjust;
|
---|
879 |
|
---|
880 | r_api->render_lines(2,line_points);
|
---|
881 |
|
---|
882 | line_points[0].px = box_x2;
|
---|
883 | line_points[0].py = box_y2 - height_adjust;
|
---|
884 |
|
---|
885 | line_points[1].px = box_x2;
|
---|
886 | line_points[1].py = box_y2;
|
---|
887 |
|
---|
888 | line_points[2].px = box_x2 - width_adjust;
|
---|
889 | line_points[2].py = box_y2;
|
---|
890 |
|
---|
891 | r_api->render_lines(2,line_points);
|
---|
892 |
|
---|
893 | line_points[0].px = box_x1 + width_adjust;
|
---|
894 | line_points[0].py = box_y2;
|
---|
895 |
|
---|
896 | line_points[1].px = box_x1;
|
---|
897 | line_points[1].py = box_y2;
|
---|
898 |
|
---|
899 | line_points[2].px = box_x1;
|
---|
900 | line_points[2].py = box_y2 - height_adjust;
|
---|
901 |
|
---|
902 | r_api->render_lines(2,line_points);
|
---|
903 |
|
---|
904 | pf_render_draw_outline.stop();
|
---|
905 | }
|
---|
906 |
|
---|
907 | int g1_sprite_depth_compare(const void *a, const void *b)
|
---|
908 | {
|
---|
909 | if (((g1_post_draw_sprite_struct *)a)->z<((g1_post_draw_sprite_struct *)b)->z)
|
---|
910 | return -1;
|
---|
911 | else if (((g1_post_draw_sprite_struct *)a)->z>((g1_post_draw_sprite_struct *)b)->z)
|
---|
912 | return 1;
|
---|
913 | else
|
---|
914 | return 0;
|
---|
915 |
|
---|
916 | }
|
---|
917 |
|
---|
918 | sw32 g1_render_class::add_post_draw_vert(r1_vert &a)
|
---|
919 | {
|
---|
920 | g1_post_draw_verts[g1_num_post_draw_verts] = a;
|
---|
921 | g1_num_post_draw_verts++;
|
---|
922 |
|
---|
923 | return (g1_num_post_draw_verts-1);
|
---|
924 | }
|
---|
925 |
|
---|
926 | sw32 g1_render_class::add_post_draw_quad(g1_post_draw_quad_class &q)
|
---|
927 | {
|
---|
928 | g1_post_draw_quads[g1_num_post_draw_quads] = q;
|
---|
929 | g1_num_post_draw_quads++;
|
---|
930 |
|
---|
931 | return (g1_num_post_draw_quads-1);
|
---|
932 | }
|
---|
933 |
|
---|
934 |
|
---|
935 | void g1_render_class::post_draw_quads()
|
---|
936 | {
|
---|
937 | int i,j;
|
---|
938 |
|
---|
939 | if (g1_num_post_draw_quads)
|
---|
940 | {
|
---|
941 |
|
---|
942 | pf_post_draw_quads.start();
|
---|
943 |
|
---|
944 |
|
---|
945 | r1_vert temp_buf_1[8];
|
---|
946 | r1_vert temp_buf_2[8];
|
---|
947 |
|
---|
948 | r_api->disable_texture();
|
---|
949 | r_api->set_alpha_mode(R1_ALPHA_LINEAR);
|
---|
950 | // r_api->set_shading_mode(R1_COLORED_SHADING);
|
---|
951 | // r_api->set_write_mode(R1_COMPARE_W | R1_WRITE_COLOR);
|
---|
952 |
|
---|
953 | int t = g1_num_post_draw_quads;
|
---|
954 |
|
---|
955 | for (i=0; i<t; i++)
|
---|
956 | {
|
---|
957 | g1_post_draw_quad_class *q = &g1_post_draw_quads[i];
|
---|
958 |
|
---|
959 | sw32 num_poly_verts = (q->vert_ref[3]==0xFFFF) ? (3) : (4);
|
---|
960 |
|
---|
961 | r1_vert *clipped_poly = r_api->clip_poly(&num_poly_verts,
|
---|
962 | g1_post_draw_verts,
|
---|
963 | q->vert_ref,
|
---|
964 | temp_buf_1,
|
---|
965 | temp_buf_2,
|
---|
966 | 0);
|
---|
967 |
|
---|
968 | if (clipped_poly && num_poly_verts>=3)
|
---|
969 | {
|
---|
970 | for (j=0; j<num_poly_verts; j++)
|
---|
971 | {
|
---|
972 | float ooz = r1_ooz(clipped_poly[j].v.z);
|
---|
973 |
|
---|
974 | clipped_poly[j].px = clipped_poly[j].v.x * ooz * center_x + center_x;
|
---|
975 | clipped_poly[j].py = clipped_poly[j].v.y * ooz * center_y + center_y;
|
---|
976 | clipped_poly[j].w = ooz;
|
---|
977 | }
|
---|
978 | r_api->render_poly(num_poly_verts,clipped_poly);
|
---|
979 | }
|
---|
980 | }
|
---|
981 |
|
---|
982 | r_api->set_alpha_mode(R1_ALPHA_DISABLED);
|
---|
983 | g1_num_post_draw_quads = 0;
|
---|
984 | g1_num_post_draw_verts = 0;
|
---|
985 |
|
---|
986 | pf_post_draw_quads.stop();
|
---|
987 |
|
---|
988 | }
|
---|
989 |
|
---|
990 | qsort(g1_post_draw_sprites, g1_t_post_draw_sprites, sizeof(g1_post_draw_sprite_struct),
|
---|
991 | g1_sprite_depth_compare);
|
---|
992 |
|
---|
993 | for (i=0; i<g1_t_post_draw_sprites; i++)
|
---|
994 | {
|
---|
995 | g1_post_draw_sprite_struct *s=g1_post_draw_sprites + i;
|
---|
996 | r1_clip_render_textured_rect(s->x1,s->y1,s->x2,s->y2, s->z,
|
---|
997 | 1.0,
|
---|
998 | i4_f_to_i(g1_render.center_x*2),
|
---|
999 | i4_f_to_i(g1_render.center_y*2),
|
---|
1000 | s->tex, 0, g1_render.r_api, s->s1, s->t1, s->s2, s->t2);
|
---|
1001 | g1_stat_counter.increment(g1_statistics_counter_class::SPRITES);
|
---|
1002 | }
|
---|
1003 |
|
---|
1004 | g1_t_post_draw_sprites=0;
|
---|
1005 |
|
---|
1006 | }
|
---|
1007 |
|
---|
1008 | void g1_render_class::clip_render_quad(g1_quad_class *q,
|
---|
1009 | r1_vert *verts,
|
---|
1010 | i4_transform_class *t,
|
---|
1011 | int current_frame)
|
---|
1012 | {
|
---|
1013 | int i;
|
---|
1014 | i4_3d_vector p;
|
---|
1015 |
|
---|
1016 | w8 ANDCODE = 0xFF;
|
---|
1017 | w8 ORCODE = 0;
|
---|
1018 |
|
---|
1019 |
|
---|
1020 | for (i=0; i<4; i++)
|
---|
1021 | {
|
---|
1022 | int vref=q->vertex_ref[i];
|
---|
1023 |
|
---|
1024 | r1_3d_point_class *v=&verts[vref].v;
|
---|
1025 |
|
---|
1026 | p=i4_3d_vector(v->x, v->y, v->z);
|
---|
1027 |
|
---|
1028 | i4_3d_vector &temp_v = (i4_3d_vector &)verts[vref].v;
|
---|
1029 | t->transform(p, temp_v);
|
---|
1030 |
|
---|
1031 | verts[vref].v.x *= scale_x;
|
---|
1032 | verts[vref].v.y *= scale_y;
|
---|
1033 |
|
---|
1034 |
|
---|
1035 | w8 code = r1_calc_outcode(verts+vref);
|
---|
1036 | ANDCODE &= code;
|
---|
1037 | }
|
---|
1038 |
|
---|
1039 | if (ANDCODE) return ;
|
---|
1040 |
|
---|
1041 | sw32 num_poly_verts = 4;
|
---|
1042 | r1_vert temp_buf_1[32];
|
---|
1043 | r1_vert temp_buf_2[32];
|
---|
1044 |
|
---|
1045 |
|
---|
1046 | r1_vert *clipped_poly = r_api->clip_poly(&num_poly_verts,
|
---|
1047 | verts,
|
---|
1048 | q->vertex_ref,
|
---|
1049 | temp_buf_1,
|
---|
1050 | temp_buf_2,
|
---|
1051 | R1_CLIP_NO_CALC_OUTCODE);
|
---|
1052 |
|
---|
1053 |
|
---|
1054 | if (clipped_poly && num_poly_verts>=3)
|
---|
1055 | {
|
---|
1056 | float nearest_w = 0;
|
---|
1057 |
|
---|
1058 | int j;
|
---|
1059 | for (j=0; j<num_poly_verts; j++)
|
---|
1060 | {
|
---|
1061 | float ooz = r1_ooz(clipped_poly[j].v.z);
|
---|
1062 | if (ooz > nearest_w)
|
---|
1063 | nearest_w=ooz;
|
---|
1064 |
|
---|
1065 | clipped_poly[j].px = clipped_poly[j].v.x * ooz * center_x + center_x;
|
---|
1066 | clipped_poly[j].py = clipped_poly[j].v.y * ooz * center_y + center_y;
|
---|
1067 | clipped_poly[j].w = ooz;
|
---|
1068 | }
|
---|
1069 |
|
---|
1070 | if (q->material_ref)
|
---|
1071 | {
|
---|
1072 | i4_float twidth = nearest_w * q->texture_scale * center_x * 2;
|
---|
1073 | r_api->use_texture(q->material_ref, i4_f_to_i(twidth), current_frame);
|
---|
1074 | }
|
---|
1075 |
|
---|
1076 | r_api->render_poly(num_poly_verts, clipped_poly);
|
---|
1077 | }
|
---|
1078 | }
|
---|
1079 |
|
---|
1080 |
|
---|
1081 | void g1_render_class::add_translucent_trail(i4_transform_class *t,
|
---|
1082 | i4_3d_point_class *spots, int t_spots,
|
---|
1083 | float start_width, float end_width,
|
---|
1084 | float start_alpha, float end_alpha,
|
---|
1085 | w32 sc, w32 ec)
|
---|
1086 |
|
---|
1087 | {
|
---|
1088 | if (t_spots<2) return;
|
---|
1089 |
|
---|
1090 | pf_add_translucent_trail.start();
|
---|
1091 |
|
---|
1092 | //make sure there's enough space in our arrays
|
---|
1093 | if ((t_spots+1)*3 > (max_post_draw_verts - g1_num_post_draw_verts))
|
---|
1094 | {
|
---|
1095 | //i4_warning("g1_render::no space for tail vertices");
|
---|
1096 | pf_add_translucent_trail.stop();
|
---|
1097 | return;
|
---|
1098 | }
|
---|
1099 |
|
---|
1100 | if ((t_spots*2) > (max_post_draw_quads - g1_num_post_draw_quads))
|
---|
1101 | {
|
---|
1102 | //i4_warning("g1_render::no space for tail polys");
|
---|
1103 | pf_add_translucent_trail.stop();
|
---|
1104 | return;
|
---|
1105 | }
|
---|
1106 |
|
---|
1107 | i4_float start_r=g1_table_0_255_to_0_1[((sc>>16)&0xff)];
|
---|
1108 | i4_float start_g=g1_table_0_255_to_0_1[((sc>>8)&0xff)];
|
---|
1109 | i4_float start_b=g1_table_0_255_to_0_1[((sc>>0)&0xff)];
|
---|
1110 |
|
---|
1111 | i4_float end_r=g1_table_0_255_to_0_1[((ec>>16)&0xff)];
|
---|
1112 | i4_float end_g=g1_table_0_255_to_0_1[((ec>>8)&0xff)];
|
---|
1113 | i4_float end_b=g1_table_0_255_to_0_1[((ec>>0)&0xff)];
|
---|
1114 |
|
---|
1115 | int i;
|
---|
1116 | i4_3d_point_class proj[256];
|
---|
1117 | i4_3d_point_class *p = proj;
|
---|
1118 |
|
---|
1119 | for (i=0; i<t_spots; i++, p++)
|
---|
1120 | t->transform(spots[i], *p);
|
---|
1121 |
|
---|
1122 | float width = start_width;
|
---|
1123 | float width_step = (end_width-start_width)/(t_spots-1);
|
---|
1124 | float next_width = start_width;
|
---|
1125 |
|
---|
1126 | float alpha_step = (end_alpha-start_alpha)/(t_spots-1);
|
---|
1127 | float r_step = (end_r-start_r)/(t_spots-1);
|
---|
1128 | float g_step = (end_g-start_g)/(t_spots-1);
|
---|
1129 | float b_step = (end_b-start_b)/(t_spots-1);
|
---|
1130 |
|
---|
1131 | i4_2d_vector perp0( -(proj[1].y-proj[0].y), proj[1].x-proj[0].x);
|
---|
1132 |
|
---|
1133 | if (perp0.x==0 && perp0.y==0)
|
---|
1134 | perp0.x=1;
|
---|
1135 | else
|
---|
1136 | perp0.normalize();
|
---|
1137 |
|
---|
1138 | float &ooxscale = scale_x;//ooscale_x;
|
---|
1139 | float &ooyscale = scale_y;//ooscale_y;
|
---|
1140 |
|
---|
1141 | int sv = g1_num_post_draw_verts;
|
---|
1142 |
|
---|
1143 | i4_float r = start_r;
|
---|
1144 | i4_float g = start_g;
|
---|
1145 | i4_float b = start_b;
|
---|
1146 | i4_float edge_alpha = 0.1;
|
---|
1147 |
|
---|
1148 | add_smoke_vert((proj[0].x + perp0.x * width) * ooxscale,
|
---|
1149 | (proj[0].y + perp0.y * width) * ooyscale,
|
---|
1150 | proj[0].z, r,g,b, edge_alpha);
|
---|
1151 |
|
---|
1152 | add_smoke_vert((proj[0].x) * ooxscale,
|
---|
1153 | (proj[0].y) * ooyscale,
|
---|
1154 | proj[0].z, r,g,b, start_alpha);
|
---|
1155 |
|
---|
1156 |
|
---|
1157 | add_smoke_vert((proj[0].x - perp0.x * width) * ooxscale,
|
---|
1158 | (proj[0].y - perp0.y * width) * ooyscale,
|
---|
1159 | proj[0].z, r,g,b, edge_alpha);
|
---|
1160 |
|
---|
1161 |
|
---|
1162 | for (i=1; i<t_spots; i++)
|
---|
1163 | {
|
---|
1164 | next_width += width_step;
|
---|
1165 | r += r_step;
|
---|
1166 | g += g_step;
|
---|
1167 | b += b_step;
|
---|
1168 | start_alpha += alpha_step;
|
---|
1169 |
|
---|
1170 | i4_2d_vector perp_last, perp_next, perp;
|
---|
1171 |
|
---|
1172 | perp_last.x =-(proj[i].y-proj[i-1].y);
|
---|
1173 | perp_last.y = (proj[i].x-proj[i-1].x);
|
---|
1174 |
|
---|
1175 | if (perp_last.x==0 && perp_last.y==0)
|
---|
1176 | perp_last.x=1;
|
---|
1177 | else
|
---|
1178 | perp_last.normalize();
|
---|
1179 |
|
---|
1180 | if (i==t_spots-1)
|
---|
1181 | perp=perp_last;
|
---|
1182 | else
|
---|
1183 | {
|
---|
1184 | perp_next.x =-(proj[i+1].y-proj[i].y);
|
---|
1185 | perp_next.y = (proj[i+1].x-proj[i].x);
|
---|
1186 |
|
---|
1187 | if (perp_next.x==0 && perp_next.y==0)
|
---|
1188 | perp_next.x=1;
|
---|
1189 | else
|
---|
1190 | perp_next.normalize();
|
---|
1191 |
|
---|
1192 | perp.x=perp_last.x + perp_next.x;
|
---|
1193 | perp.y=perp_last.y + perp_next.y;
|
---|
1194 |
|
---|
1195 | if (perp.x==0 && perp.y==0)
|
---|
1196 | perp.x=1;
|
---|
1197 | else
|
---|
1198 | perp.normalize();
|
---|
1199 | }
|
---|
1200 |
|
---|
1201 | add_smoke_vert((proj[i].x + perp.x * next_width) * ooxscale,
|
---|
1202 | (proj[i].y + perp.y * next_width) * ooyscale,
|
---|
1203 | proj[i].z, r,g,b, edge_alpha);
|
---|
1204 |
|
---|
1205 | add_smoke_vert((proj[i].x) * ooxscale,
|
---|
1206 | (proj[i].y) * ooyscale,
|
---|
1207 | proj[i].z, r,g,b, start_alpha);
|
---|
1208 |
|
---|
1209 | add_smoke_vert((proj[i].x - perp.x * next_width) * ooxscale,
|
---|
1210 | (proj[i].y - perp.y * next_width) * ooyscale,
|
---|
1211 | proj[i].z, r,g,b, edge_alpha);
|
---|
1212 |
|
---|
1213 | g1_post_draw_quad_class q1(sv+ i*3,
|
---|
1214 | sv + i*3+1,
|
---|
1215 | sv + i*3-2,
|
---|
1216 | sv + i*3-3);
|
---|
1217 | add_post_draw_quad(q1);
|
---|
1218 |
|
---|
1219 | g1_post_draw_quad_class q2(sv +i*3+1,
|
---|
1220 | sv + i*3+2,
|
---|
1221 | sv + i*3-1,
|
---|
1222 | sv + i*3-2);
|
---|
1223 | add_post_draw_quad(q2);
|
---|
1224 | }
|
---|
1225 |
|
---|
1226 | pf_add_translucent_trail.stop();
|
---|
1227 | }
|
---|
1228 |
|
---|
1229 |
|
---|
1230 | inline g1_map_vertex_class *g1vmin(g1_map_vertex_class *v1,
|
---|
1231 | g1_map_vertex_class *v2)
|
---|
1232 | {
|
---|
1233 | if (v1->height<v2->height)
|
---|
1234 | return v1;
|
---|
1235 | else return v2;
|
---|
1236 | }
|
---|
1237 |
|
---|
1238 |
|
---|
1239 | i4_bool g1_render_class::project_point(const i4_3d_point_class &p,
|
---|
1240 | r1_vert &v,
|
---|
1241 | i4_transform_class *transform)
|
---|
1242 | {
|
---|
1243 | i4_3d_vector &temp_v = (i4_3d_vector &)v.v;
|
---|
1244 | transform->transform(p,temp_v);
|
---|
1245 | v.v.x *= scale_x;
|
---|
1246 | v.v.y *= scale_y;
|
---|
1247 |
|
---|
1248 | if (v.v.z>0.001)
|
---|
1249 | {
|
---|
1250 | float ooz = r1_ooz(v.v.z);
|
---|
1251 |
|
---|
1252 | v.px = v.v.x * ooz * center_x + center_x;
|
---|
1253 | v.py = v.v.y * ooz * center_y + center_y;
|
---|
1254 |
|
---|
1255 | v.w = ooz;
|
---|
1256 |
|
---|
1257 | return i4_T;
|
---|
1258 | } else return i4_F;
|
---|
1259 | }
|
---|
1260 |
|
---|
1261 |
|
---|
1262 | void g1_render_class::draw_rectangle(int sx1, int sy1, int sx2, int sy2, i4_color col,
|
---|
1263 | i4_draw_context_class &context)
|
---|
1264 | {
|
---|
1265 | sw32 x1,y1,x2,y2;
|
---|
1266 | if (sx1<sx2) { x1=sx1; x2=sx2; } else { x1=sx2; x2=sx1; }
|
---|
1267 | if (sy1<sy2) { y1=sy1; y2=sy2; } else { y1=sy2; y2=sy1; }
|
---|
1268 |
|
---|
1269 | r_api->set_shading_mode(R1_SHADE_DISABLED);
|
---|
1270 |
|
---|
1271 | r1_clip_clear_area(x1,y1,x2,y1, col, 0.01, context, r_api);
|
---|
1272 | r1_clip_clear_area(x2,y1,x2,y2, col, 0.01, context, r_api);
|
---|
1273 | r1_clip_clear_area(x1,y2,x2,y2, col, 0.01, context, r_api);
|
---|
1274 | r1_clip_clear_area(x1,y1,x1,y2, col, 0.01, context, r_api);
|
---|
1275 | }
|
---|
1276 |
|
---|
1277 |
|
---|
1278 | #define V0 0,1
|
---|
1279 | #define V1 1,1
|
---|
1280 | #define V2 1,0
|
---|
1281 | #define V3 0,0
|
---|
1282 |
|
---|
1283 | void g1_setup_tri_texture_coords(r1_vert *tri1, r1_vert *tri2,
|
---|
1284 | int cell_rotation, int cell_is_mirrored)
|
---|
1285 | {
|
---|
1286 | float u[4]={0,1,1,0};
|
---|
1287 | float v[4]={1,1,0,0};
|
---|
1288 |
|
---|
1289 | int dir=cell_is_mirrored ? 1 : 3, on=cell_rotation;
|
---|
1290 |
|
---|
1291 | tri1[0].s=u[on];
|
---|
1292 | tri1[0].t=v[on];
|
---|
1293 | on=(on+dir)&3;
|
---|
1294 |
|
---|
1295 | tri1[1].s=u[on];
|
---|
1296 | tri1[1].t=v[on];
|
---|
1297 | on=(on+dir)&3;
|
---|
1298 |
|
---|
1299 | tri1[2].s=u[on];
|
---|
1300 | tri1[2].t=v[on];
|
---|
1301 |
|
---|
1302 |
|
---|
1303 | on=cell_rotation;
|
---|
1304 |
|
---|
1305 | tri2[0].s=u[on];
|
---|
1306 | tri2[0].t=v[on];
|
---|
1307 | on=(on+dir+dir)&3;
|
---|
1308 |
|
---|
1309 | tri2[1].s=u[on];
|
---|
1310 | tri2[1].t=v[on];
|
---|
1311 | on=(on+dir)&3;
|
---|
1312 |
|
---|
1313 | tri2[2].s=u[on];
|
---|
1314 | tri2[2].t=v[on];
|
---|
1315 | }
|
---|
1316 |
|
---|
1317 |
|
---|
1318 |
|
---|
1319 |
|
---|
1320 | void g1_render_class::render_sprite(const i4_3d_vector &p,
|
---|
1321 | r1_texture_handle tex,
|
---|
1322 | float sprite_width, float sprite_height,
|
---|
1323 | float s1, float t1, float s2, float t2)
|
---|
1324 | {
|
---|
1325 |
|
---|
1326 | if (p.z >= r1_near_clip_z)
|
---|
1327 | {
|
---|
1328 | if (g1_t_post_draw_sprites<G1_MAX_SPRITES)
|
---|
1329 | {
|
---|
1330 | g1_post_draw_sprite_struct *s=g1_post_draw_sprites + g1_t_post_draw_sprites;
|
---|
1331 |
|
---|
1332 | float ooz = r1_ooz(p.z);
|
---|
1333 |
|
---|
1334 | i4_float xs = g1_render.center_x * ooz * g1_render.scale_x;
|
---|
1335 | i4_float ys = g1_render.center_y * ooz * g1_render.scale_y;
|
---|
1336 |
|
---|
1337 | float cx=g1_render.center_x + p.x*xs;
|
---|
1338 | float cy=g1_render.center_y + p.y*ys;
|
---|
1339 | float w=sprite_width * g1_render.center_x * ooz;
|
---|
1340 | float h=sprite_height * g1_render.center_x * ooz;
|
---|
1341 |
|
---|
1342 | s->x1=cx-w/2; s->y1=cy-h/2;
|
---|
1343 | s->x2=cx+w/2; s->y2=cy+h/2;
|
---|
1344 |
|
---|
1345 | s->z=p.z;
|
---|
1346 | s->tex=tex;
|
---|
1347 | s->s1=s1; s->t1=t1; s->s2=s2; s->t2=t2;
|
---|
1348 |
|
---|
1349 | g1_t_post_draw_sprites++;
|
---|
1350 | }
|
---|
1351 | }
|
---|
1352 | }
|
---|
1353 |
|
---|
1354 |
|
---|
1355 | void g1_render_class::render_near_sprite(float px, float py,
|
---|
1356 | r1_texture_handle tex,
|
---|
1357 | float sprite_width, float sprite_height,
|
---|
1358 | float s1, float t1, float s2, float t2)
|
---|
1359 | {
|
---|
1360 | if (g1_t_post_draw_sprites<G1_MAX_SPRITES)
|
---|
1361 | {
|
---|
1362 | g1_post_draw_sprite_struct *s=g1_post_draw_sprites + g1_t_post_draw_sprites;
|
---|
1363 | s->x1=px-sprite_width/2; s->y1=py-sprite_height/2;
|
---|
1364 | s->x2=px+sprite_width/2; s->y2=py+sprite_height/2;
|
---|
1365 |
|
---|
1366 | s->z=r1_near_clip_z;
|
---|
1367 | s->tex=tex;
|
---|
1368 | s->s1=s1; s->t1=t1; s->s2=s2; s->t2=t2;
|
---|
1369 |
|
---|
1370 | g1_t_post_draw_sprites++;
|
---|
1371 | }
|
---|
1372 | }
|
---|
1373 |
|
---|