1 /* Wazp3D Beta 52 : Alain THELLIER - Paris - FRANCE - (November 2006 to 2012) */
2 /* Adaptation to AROS from Matthias Rustler */
3 /* Code clean-up and library enhancements from Gunther Nikl */
4 /* LICENSE: GNU General Public License (GNU GPL) for this file */
6 /* This file contain the SOFT3D rasterizer that truly draw the pixels */
9 #include "soft3d_protos.h"
10 #include "soft3d_opengl.h"
12 /* use a local pointer on Wazp3D : having a copy here allow to separate the sof3d binary & wazp3d binary*/
15 struct WAZP3D_parameters
*Wazp3D
; /* local pointer to the struct in Warp3d.library */
16 #include "soft3d_mem_print.h" /* memory and print/debug functions : usually in Warp3d.c */
20 #if !defined(AMIGA) /* so we are compiling the DLL */
21 #include "soft3d_pc_glue.h"
23 #define SLOWCPU 1 /* OS3 68k */
27 #undef SLOWCPU /* OS4 ppc */
30 /*==================================================================================*/
31 /* structures definitions only used in SOFT3D */
125 /*=============================================================*/
132 UBYTE empty1
,empty2
,a
,b
;
141 UBYTE b
,a
,empty3
,empty4
;
145 /*=============================================================*/
154 /*=============================================================*/
155 struct AvailableFunctions
{
156 HOOKEDFUNCTION Fill
[8]; /* functions available */
157 HOOKEDFUNCTION Edge
[16];
158 HOOKEDFUNCTION TexEnv
[6*2+1];
159 HOOKEDFUNCTION Ztest
[16];
160 HOOKEDFUNCTION BlendFast
[256];
162 struct AvailableFunctions Functions
;
163 /*=============================================================*/
164 struct SOFT3D_context
{
166 UBYTE Mul8
[256*256]; /* table for multiplying two UBYTE */
167 UBYTE Add8
[256*256]; /* table for adding two UBYTE with overflow */
168 UBYTE Fil8
[256*256]; /* table for filtering two UBYTE */
170 ULONG B0toRGBA32
[256]; /* tables for converting 8/15/16 bits to RGBA */
171 ULONG B1toRGBA32
[256];
178 WORD large
,high
,bits
;
180 struct vertex3D ClipMin
; /* 3D clipper */
181 struct vertex3D ClipMax
;
183 ULONG
*ImageBuffer32
;
187 struct SOFT3D_mipmap
*MM
;
190 WORD PointLarges
[MAXSCREEN
];
191 union pixel3D edge1
[MAXSCREEN
];
192 union pixel3D edge2
[MAXSCREEN
];
193 union pixel3D edgeM
[MAXSCREEN
];
194 UWORD Image8X
[MAXSCREEN
];
195 UBYTE Ztest
[MAXSCREEN
];
196 HOOKEDFUNCTION FunctionPoly
; /* functions currently used in pipeline */
197 HOOKEDFUNCTION FunctionEdge
;
198 HOOKEDFUNCTION FunctionFill
;
199 HOOKEDFUNCTION FunctionZtest
;
200 HOOKEDFUNCTION FunctionIn
;
201 HOOKEDFUNCTION FunctionBlend
;
202 HOOKEDFUNCTION FunctionBlendFast
;
203 HOOKEDFUNCTION FunctionTexEnv
;
204 HOOKEDFUNCTION FunctionFog
;
205 HOOKEDFUNCTION FunctionFilter
;
206 HOOKEDFUNCTION FunctionSepia
;
207 HOOKEDFUNCTION FunctionOut
;
208 HOOKEDFUNCTION FunctionBitmapOut
;
209 HOOKEDFUNCTION FunctionBitmapIn
;
210 HOOKEDFUNCTION FunctionWriteImageBuffer
;
211 struct fragbuffer3D FragBuffer
[FRAGBUFFERSIZE
];
212 struct fragbuffer3D
*FragBufferDone
; /* last pixel written in FragBuffer */
213 struct fragbuffer3D
*FragBufferMaxi
; /* dont fill FragBuffer beyond this limit ==> flush it*/
214 ULONG FragSize2
; /* nb pixels = FragSize*2 */
215 ULONG FogRGBAs
[FOGSIZE
];
217 union pixel3D PolyPix
[MAXPOLY
];
218 union pixel3D
*P1
; /* do FunctionEdge/FunctionPoly from P1 to P2 */
220 ULONG PolyHigh
,PolyLarge
;
221 struct point3D PolyP
[MAXPOLY
];
222 struct point3D T1
[MAXPOLY
];
223 struct point3D T2
[MAXPOLY
];
225 WORD Pxmin
,Pxmax
,Pymin
,Pymax
; /* really updated region */
227 WORD xUpdate
,largeUpdate
,yUpdate
,highUpdate
; /* really updated region previous frame*/
229 UBYTE SrcFunc
,DstFunc
;
230 UBYTE UseFunctionBitmapIn
;
231 UBYTE ColorChange
; /* V41: Soft3D can smartly desactivate the gouraud if all points got the same color */
232 UBYTE ColorTransp
; /* V43: Soft3D detect if points got alpha value */
233 UBYTE ColorWhite
; /* V47: Soft3D detect if points are all white ==> no coloring */
237 struct state3D state
;
238 struct HARD3D_context HC
;
239 #ifdef AMIGA /* of course the PC DLL cant manipulate an Amiga's bitmap */
241 void *bmHandle
; /* to directly write to bitmap */
242 struct RastPort rastport
;
246 /*=================================================================*/
247 struct SOFT3D_mipmap
{
248 UBYTE
*Tex8V
[256]; /* adresse of the texture at this line */
253 /*=================================================================*/
255 struct SOFT3D_texture
{
256 struct SOFT3D_mipmap MMs
[NBMIPMAPS
];
257 UBYTE
*pt
; /* original data from 3Dprog as RGB or RGBA */
258 UBYTE
*ptmm
; /* mipmaps as RGB or RGBA */
259 UWORD large
,high
,format
,bits
;
265 struct HARD3D_texture HT
;
267 /*=================================================================*/
269 UBYTE font8x8
[14*16*8] = {
270 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
271 0,8,24,24,8,0,16,8,8,16,24,0,0,0,0,8,
272 0,8,24,60,28,36,40,8,16,8,24,8,0,0,0,8,
273 0,8,0,24,24,8,20,0,16,8,0,28,0,24,0,24,
274 0,0,0,60,12,16,40,0,16,8,0,8,0,0,0,16,
275 0,8,0,24,28,36,20,0,16,8,0,0,8,0,8,16,
276 0,0,0,0,8,0,0,0,8,16,0,0,8,0,0,0,
277 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
278 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
279 28,8,28,24,4,28,28,28,28,28,0,0,0,0,0,16,
280 20,24,4,4,12,16,16,4,20,20,0,0,0,0,0,8,
281 20,8,28,12,20,28,28,8,28,28,8,8,8,0,16,16,
282 20,8,16,4,28,4,20,8,20,4,0,0,16,24,8,0,
283 28,8,28,24,4,28,28,8,28,28,8,8,8,0,16,16,
284 0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,
285 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
286 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
287 24,24,56,24,56,28,28,28,36,8,4,36,16,34,36,24,
288 36,24,36,36,36,16,16,32,36,8,4,40,16,54,52,36,
289 90,36,56,32,36,24,24,44,60,8,4,48,16,42,44,36,
290 94,60,36,36,36,16,16,36,36,8,20,40,16,34,36,36,
291 32,36,56,24,56,28,16,28,36,8,24,36,28,34,36,24,
292 24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
293 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
294 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
295 56,24,56,28,28,36,20,34,20,20,28,24,16,24,8,0,
296 36,36,36,32,8,36,20,42,20,20,4,16,16,8,20,0,
297 56,36,56,24,8,36,20,42,8,8,8,16,24,8,0,0,
298 32,40,36,4,8,36,8,20,20,8,16,16,8,8,0,0,
299 32,20,36,56,8,24,8,20,20,8,28,16,8,8,0,0,
300 0,0,0,0,0,0,0,0,0,0,0,24,0,24,0,60,
301 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
302 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
303 16,0,16,0,4,0,24,0,16,8,8,16,8,0,0,0,
304 8,0,16,0,4,8,16,0,16,0,0,16,8,0,0,0,
305 0,12,28,28,28,28,24,28,28,8,8,20,8,54,24,28,
306 0,20,20,16,20,16,16,20,20,8,8,24,8,42,20,20,
307 0,12,28,28,28,28,16,28,20,8,8,20,8,42,20,28,
308 0,0,0,0,0,0,0,4,0,0,8,0,0,0,0,0,
309 0,0,0,0,0,0,0,28,0,0,0,0,0,0,0,0,
310 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
311 0,0,0,0,0,0,0,0,0,0,0,8,8,16,12,0,
312 0,0,0,0,16,0,0,0,0,0,0,8,8,16,24,0,
313 24,12,24,24,24,20,20,36,20,20,28,16,8,8,0,0,
314 20,20,16,16,16,20,20,36,8,20,8,16,8,8,0,0,
315 24,12,16,48,8,12,8,60,20,8,28,8,8,16,0,0,
316 16,4,0,0,0,0,0,0,0,16,0,8,0,16,0,0,
317 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
318 0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,
319 8,0,0,12,0,0,8,8,8,20,28,0,62,0,8,0,
320 8,0,0,8,0,0,28,28,20,40,32,0,40,0,8,0,
321 8,0,0,28,0,0,8,8,0,26,24,8,44,0,8,0,
322 8,0,0,8,0,0,8,8,0,20,4,16,40,0,8,0,
323 8,0,8,8,40,84,8,28,0,42,56,8,62,0,8,0,
324 0,0,8,16,40,0,8,8,0,0,0,0,0,0,0,0,
325 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
326 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
327 0,8,8,24,24,0,0,0,12,122,40,0,0,0,8,20,
328 0,0,0,0,0,0,0,0,24,46,0,0,0,0,8,20,
329 0,0,0,0,0,24,0,0,0,42,24,16,28,0,8,8,
330 0,0,0,0,0,24,28,62,0,0,16,8,42,0,8,8,
331 0,0,0,0,0,0,0,0,0,0,48,16,28,0,8,8,
332 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
333 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
334 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
335 0,0,0,4,20,20,8,12,24,24,8,0,0,0,24,60,
336 0,8,4,8,8,28,8,24,0,44,8,0,0,0,52,0,
337 0,0,12,28,20,8,8,20,0,52,0,8,0,0,44,0,
338 0,8,16,8,0,28,8,12,0,24,0,16,28,8,24,0,
339 0,8,12,12,0,8,8,12,0,0,0,8,4,0,0,0,
340 0,8,8,0,0,0,8,24,0,0,0,0,0,0,0,0,
341 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
342 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
343 0,0,8,0,8,0,0,0,0,0,0,0,0,0,0,0,
344 8,0,8,8,16,0,24,0,0,8,8,0,36,36,36,8,
345 0,24,0,8,0,40,24,8,0,8,8,16,40,40,40,0,
346 0,24,0,0,0,40,8,0,0,0,0,8,20,20,20,8,
347 0,24,0,0,0,52,8,0,8,0,0,16,36,36,36,16,
348 0,0,0,0,0,32,8,0,24,0,0,0,0,0,0,8,
349 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
350 8,8,8,8,8,8,14,24,28,28,28,28,8,16,40,0,
351 20,20,20,20,20,20,24,36,16,16,16,16,0,0,0,16,
352 20,20,20,20,20,20,46,32,28,28,28,28,8,16,16,16,
353 28,28,28,28,28,28,56,36,16,16,16,16,8,16,16,16,
354 20,20,20,20,20,20,46,24,28,28,28,28,8,16,16,16,
355 0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,
356 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
357 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
358 0,24,16,8,24,24,36,0,0,16,8,24,24,8,0,0,
359 24,36,24,24,24,24,24,0,28,36,36,36,36,20,16,8,
360 20,52,36,36,36,36,36,20,44,36,36,36,36,20,28,20,
361 52,44,36,36,36,36,36,8,52,36,36,36,36,8,20,28,
362 20,36,36,36,36,36,36,20,52,36,36,36,36,8,28,20,
363 24,36,24,24,24,24,24,0,56,24,24,24,24,8,16,24,
364 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
365 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
366 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
367 8,4,12,12,20,8,0,0,16,8,8,20,16,8,16,0,
368 4,8,0,0,0,0,0,0,8,16,20,0,8,16,40,40,
369 12,12,12,12,12,12,28,12,24,24,24,24,0,0,0,0,
370 20,20,20,20,20,20,42,16,20,20,20,20,8,16,16,16,
371 12,12,12,12,12,12,30,12,12,12,12,12,8,16,16,16,
372 0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,
373 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
374 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
375 0,24,16,4,8,12,20,0,0,16,4,8,20,4,16,20,
376 16,0,8,8,20,0,0,0,0,8,8,20,0,8,16,0,
377 8,24,28,28,28,28,28,8,28,20,20,20,20,20,24,20,
378 24,20,20,20,20,20,20,28,28,20,20,20,20,8,20,8,
379 24,20,28,28,28,28,28,8,28,12,12,12,12,8,24,8,
380 0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,
381 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
384 /*=================================================================*/
385 void PrintST(struct SOFT3D_texture
*ST
)
389 if (!Wazp3D
->DebugST
.ON
) return;
390 Libprintf("SOFT3D_texture(%ld) %s pt %ld NextST(%ld) TexFlags %ld \n",(IPTR
)ST
,ST
->name
,(IPTR
)ST
->pt
,(IPTR
)ST
->nextST
,(ULONG
)ST
->TexFlags
);
395 /*=================================================================*/
396 void PrintPix(union pixel3D
*Pix
)
399 if (!Wazp3D
->DebugPoint
.ON
) return;
400 if (!Wazp3D
->DebugSOFT3D
.ON
) return;
401 Libprintf(" Pix XY %ld %ld \tUV %ld %ld ",(LONG
)Pix
->W
.x
,(LONG
)Pix
->W
.y
,(LONG
)Pix
->W
.u
,(LONG
)Pix
->W
.v
);
402 Libprintf("RGBA %ld %ld %ld %ld large %ld",(LONG
)Pix
->W
.R
,(LONG
)Pix
->W
.G
,(LONG
)Pix
->W
.B
,(LONG
)Pix
->W
.A
,(LONG
)Pix
->W
.large
);
403 Libprintf(" ZWF "); pf((float)Pix
->L
.z
); pf(Pix
->L
.w
); pf(Pix
->W
.F
);Libprintf("\n");
408 /*=================================================================*/
409 void PrintP2(struct point3D
*P
)
412 Libprintf("ClipXYZW; %ld; %ld; %ld; %ld; UV; %ld; %ld\n",(ULONG
)P
->x
,(ULONG
)P
->y
,(ULONG
)(1000.0*P
->z
),(ULONG
)(1000.0*P
->w
),(ULONG
)(P
->u
),(ULONG
)(P
->v
));
417 /*=================================================================*/
418 /* SOFT3D internal private functions */
419 void AntiAliasImage(void *image
,UWORD large
,UWORD high
);
420 void ClipPoly(struct SOFT3D_context
*SC
);
421 void ClipLine(struct SOFT3D_context
*SC
);
422 void CreateMipmaps(struct SOFT3D_texture
*ST
);
423 void DrawLinePix(struct SOFT3D_context
*SC
);
424 void DrawPointPix(struct SOFT3D_context
*SC
);
425 void DrawSimplePix(struct SOFT3D_context
*SC
,register union pixel3D
*P
);
426 void DrawPolyP(struct SOFT3D_context
*SC
);
427 void DrawPolyPix(struct SOFT3D_context
*SC
);
428 void DrawTriP(struct SOFT3D_context
*SC
,register struct point3D
*A
,register struct point3D
*B
,register struct point3D
*C
);
429 void Fill_BigTexPersp2_Gouraud_Fog(struct SOFT3D_context
*SC
);
430 void Fill_BigTexPersp2(struct SOFT3D_context
*SC
);
431 void Fill_Flat(struct SOFT3D_context
*SC
);
432 void Fill_Fog(struct SOFT3D_context
*SC
);
433 void Fill_Gouraud(struct SOFT3D_context
*SC
);
434 void Fill_Gouraud_Fog(struct SOFT3D_context
*SC
);
435 void Fill_Tex(struct SOFT3D_context
*SC
);
436 void Fill_Tex_Fog(struct SOFT3D_context
*SC
);
437 void Fill_Tex_Gouraud(struct SOFT3D_context
*SC
);
438 void Fill_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
);
439 BOOL
LockBM(struct SOFT3D_context
*SC
);
440 void PixelsARGB(struct SOFT3D_context
*SC
);
441 void PixelsAdd24(struct SOFT3D_context
*SC
);
442 void PixelsAdd32(struct SOFT3D_context
*SC
);
443 void PixelsSub24(struct SOFT3D_context
*SC
);
444 void PixelsSub32(struct SOFT3D_context
*SC
);
445 void PixelsBlend24(struct SOFT3D_context
*SC
);
446 void PixelsBlend32(struct SOFT3D_context
*SC
);
447 void PixelsDecal24(struct SOFT3D_context
*SC
);
448 void PixelsDecal32(struct SOFT3D_context
*SC
);
449 void PixelsInOutBGRA(struct SOFT3D_context
*SC
);
450 void PixelsModulate24(struct SOFT3D_context
*SC
);
451 void PixelsModulate32(struct SOFT3D_context
*SC
);
452 void PixelsOne_One24(struct SOFT3D_context
*SC
);
453 void PixelsReplace24(struct SOFT3D_context
*SC
);
454 void PixelsReplace32(struct SOFT3D_context
*SC
);
455 void PixelsOne_Zero32(struct SOFT3D_context
*SC
);
456 void PixelsSrcAlpha_OneMinusSrcAlpha32(struct SOFT3D_context
*SC
);
457 void PixelsSrcAlpha_One32(struct SOFT3D_context
*SC
);
458 void PixelsOne_One24(struct SOFT3D_context
*SC
);
459 void PixelsZero_SrcAlpha32(struct SOFT3D_context
*SC
);
460 void PixelsZero_SrcColor24(struct SOFT3D_context
*SC
);
461 void PixelsDstColor_Zero24(struct SOFT3D_context
*SC
);
462 void PixelsZero_OneMinusSrcColor24(struct SOFT3D_context
*SC
);
463 void PixelsSrcAlpha_OneMinusSrcColor32(struct SOFT3D_context
*SC
);
464 void PixelsOne_OneMinusSrcAlpha32(struct SOFT3D_context
*SC
);
465 void PixelsSrcAlpha_OneMinusSrcAlpha32fast(struct SOFT3D_context
*SC
);
466 void PixelsSrcAlpha_OneMinusSrcAlpha32perfect(struct SOFT3D_context
*SC
);
467 void PixelsChroma32fast(struct SOFT3D_context
*SC
);
468 void PrintPix(union pixel3D
*Pix
);
469 void PrintST(struct SOFT3D_texture
*ST
);
470 void ReduceBitmap(UBYTE
*pt
,UBYTE
*pt2
,UWORD large
,UWORD high
, WORD bits
,WORD ratio
);
471 void UnLockBM(struct SOFT3D_context
*SC
);
472 void UVtoRGBA(struct SOFT3D_texture
*ST
,float u
,float v
,UBYTE
*RGBA
);
473 void Ztest_zalways(struct SOFT3D_context
*SC
);
474 void Ztest_zalways_update(struct SOFT3D_context
*SC
);
475 void Ztest_zequal(struct SOFT3D_context
*SC
);
476 void Ztest_zequal_update(struct SOFT3D_context
*SC
);
477 void Ztest_zgequal(struct SOFT3D_context
*SC
);
478 void Ztest_zgequal_update(struct SOFT3D_context
*SC
);
479 void Ztest_zgreater(struct SOFT3D_context
*SC
);
480 void Ztest_zgreater_update(struct SOFT3D_context
*SC
);
481 void Ztest_zlequal(struct SOFT3D_context
*SC
);
482 void Ztest_zlequal_update(struct SOFT3D_context
*SC
);
483 void Ztest_zless(struct SOFT3D_context
*SC
);
484 void Ztest_zless_update(struct SOFT3D_context
*SC
);
485 void Ztest_znequal(struct SOFT3D_context
*SC
);
486 void Ztest_znequal_update(struct SOFT3D_context
*SC
);
487 void Ztest_znever_update(struct SOFT3D_context
*SC
);
488 void Ztest_znotequal(struct SOFT3D_context
*SC
);
489 void Ztest_znotequal_update(struct SOFT3D_context
*SC
);
490 void PixelsOut8(struct SOFT3D_context
*SC
);
491 void PixelsIn8(struct SOFT3D_context
*SC
);
492 void PixelsOut16(struct SOFT3D_context
*SC
);
493 void PixelsIn16(struct SOFT3D_context
*SC
);
494 void PixelsBlendFunctionAll(struct SOFT3D_context
*SC
);
495 void Poly_Persp0_Tex(struct SOFT3D_context
*SC
);
496 void Poly_Persp0_Gouraud(struct SOFT3D_context
*SC
);
497 void Poly_Persp0_Flat(struct SOFT3D_context
*SC
);
498 void Poly_Persp0_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
);
499 void Poly_Persp1_Tex(struct SOFT3D_context
*SC
);
500 void Poly_Persp1_Gouraud(struct SOFT3D_context
*SC
);
501 void Poly_Persp1_Flat(struct SOFT3D_context
*SC
);
502 void Poly_Persp1_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
);
503 void Poly_Persp2x2_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
);
504 void Edge_Persp_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
);
505 void Edge_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
);
506 void Edge_Gouraud(struct SOFT3D_context
*SC
);
507 void Edge_Flat(struct SOFT3D_context
*SC
);
508 void Edge_Persp_Tex(struct SOFT3D_context
*SC
);
509 void Edge_Tex(struct SOFT3D_context
*SC
);
510 void ChangeSoftPoint(APTR sc
);
511 void SOFT3D_SetDrawFunctions(APTR sc
);
512 /*==========================================================================*/
515 #define OS4COMPOSITING 1
516 #include "soft3d_compositing.c" /* use OS4 compositing engine as hardware renderer */
519 /*==========================================================================*/
520 void WriteImageBuffer(struct SOFT3D_context
*SC
)
523 WritePixelArray(SC
->ImageBuffer32
,SC
->xUpdate
,SC
->yUpdate
,SC
->large
*(32/8),&SC
->rastport
,SC
->xUpdate
,SC
->yUpdate
+SC
->yoffset
,SC
->largeUpdate
,SC
->highUpdate
,RECTFMT_RGBA
);
526 /*==========================================================================*/
527 void SetImage(APTR sc
,UWORD x
,UWORD y
,UWORD large
,UWORD high
,UWORD bits
,UBYTE
*Image8
)
529 struct SOFT3D_context
*SC
=sc
;
541 if(Image8
==NULL
) return;
544 offset
=y
*large
*bits
/8 + x
*bits
/8; /* Dont use x y offset in SOFT3D : use real pointer to Image */
545 SC
->Image8
=Image8
=Image8
+offset
;
553 SC
->FragBufferMaxi
=SC
->FragBuffer
+ (FRAGBUFFERSIZE
- SC
->large
- 4);
562 SC
->edge1
[y
].L
.Image8Y
=Image8
; SC
->edge1
[y
].L
.y
=0; SC
->edge1
[y
].W
.y
=y
;SC
->edge1
[y
].L
.bpp
=bpp
;
563 SC
->edge2
[y
].L
.Image8Y
=Image8
; SC
->edge2
[y
].L
.y
=0; SC
->edge2
[y
].W
.y
=y
;SC
->edge2
[y
].L
.bpp
=bpp
;
564 SC
->edgeM
[y
].L
.Image8Y
=Image8
; SC
->edgeM
[y
].L
.y
=0; SC
->edgeM
[y
].W
.y
=y
;SC
->edgeM
[y
].L
.bpp
=bpp
;
569 SC
->Image8X
[x
]=x
*bpp
;
573 /*=============================================================*/
574 void SOFT3D_AllocImageBuffer(APTR sc
,UWORD large
,UWORD high
)
576 struct SOFT3D_context
*SC
=sc
;
579 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
580 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
582 SFUNCTION(SOFT3D_AllocImageBuffer
)
586 if(SC
->ImageBuffer32
!=NULL
)
587 { SREM(changing ImageBuffer
...); }
589 FREEPTR(SC
->ImageBuffer32
);
591 size
=large
*high
*32/8;
593 SC
->ImageBuffer32
=MYmalloc(size
,"SOFT3D_ImageBuffer32");
594 SetImage(SC
,0,0,large
,high
,32,(UBYTE
*)SC
->ImageBuffer32
);
596 Libprintf("WAZP3D/SOFT3D: cant use Soft to bitmap!!!\n");
599 /*=============================================================*/
600 void SOFT3D_Debug(APTR txt
)
601 /* to do a printf from WinUAE */
606 /*=============================================================*/
607 BOOL
SOFT3D_Init(void *exec
)
609 SFUNCTION(SOFT3D_Init
)
612 firstME
=NULL
; /* Tracked memory-allocation */
613 if(OpenAmigaLibraries(exec
)==FALSE
) return(FALSE
);
619 /*=============================================================*/
622 SFUNCTION(SOFT3D_Close
)
626 CloseAmigaLibraries();
631 /*=============================================================*/
632 APTR
SOFT3D_AllocZbuffer(APTR sc
,UWORD large
,UWORD high
)
634 struct SOFT3D_context
*SC
=sc
;
638 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
639 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
640 SFUNCTION(SOFT3D_AllocZbuffer
)
645 if(SC
->Zbuffer
!=NULL
) /* only happen in software mode */
646 { SREM(will change an existing Zbuffer
...); }
648 FREEPTR(SC
->Zbuffer
);
652 SC
->Zbuffer
=Zbuffer
=MYmalloc(large
*high
*sizeof(ZBUFF
),"Zbuffer");
656 { SC
->edge1
[y
].L
.ZbufferY
= SC
->edge2
[y
].L
.ZbufferY
=SC
->edgeM
[y
].L
.ZbufferY
=Zbuffer
;Zbuffer
+=large
;}
661 HARD3D_AllocZbuffer(&SC
->HC
,large
,high
);
662 SC
->Zbuffer
=NULL
; /* hard cant give the zbuffer adress */
667 /*=============================================================*/
668 void *SOFT3D_Start(APTR PrefsWazp3D
)
670 struct SOFT3D_context
*SC
;
671 UBYTE ZMode
,FillMode
;
681 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
682 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
684 Wazp3D
->UseDLL
=FALSE
; /* will inform Wazp3D that soft3d is Amiga native */
686 Wazp3D
->UseDLL
=TRUE
; /* then we are runnig soft3d compiled as a PC DLL */
690 SVAR(sizeof(union pixel3D
))
691 SVAR(sizeof(union oper3D
))
692 SVAR(sizeof(struct fragbuffer3D
))
693 SVAR(sizeof(struct HARD3D_context
))
694 SVAR(sizeof(struct SOFT3D_context
))
695 SVAR(sizeof(struct SOFT3D_mipmap
))
696 SVAR(sizeof(struct SOFT3D_texture
))
697 SVAR(sizeof(struct state3D
))
700 SFUNCTION(SOFT3D_Start
)
703 SC
=MYmalloc(sizeof(struct SOFT3D_context
),"SOFT3D_context");
704 if(SC
==NULL
) return(NULL
);
705 SC
->large
=SC
->high
=0; /* undefined now */
709 InitRastPort(&SC
->rastport
);
712 /* ZCompareMode is from 1 to 8 */
713 ZMode
=ZMODE(0,W3D_Z_NEVER
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_znever_update
; /* same as Ztest_znever */
714 ZMode
=ZMODE(0,W3D_Z_LESS
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zless
;
715 ZMode
=ZMODE(0,W3D_Z_GEQUAL
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zgequal
;
716 ZMode
=ZMODE(0,W3D_Z_LEQUAL
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zlequal
;
717 ZMode
=ZMODE(0,W3D_Z_GREATER
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zgreater
;
718 ZMode
=ZMODE(0,W3D_Z_NOTEQUAL
);Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_znotequal
;
719 ZMode
=ZMODE(0,W3D_Z_EQUAL
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zequal
;
720 ZMode
=ZMODE(0,W3D_Z_ALWAYS
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zalways
;
722 ZMode
=ZMODE(1,W3D_Z_NEVER
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_znever_update
;
723 ZMode
=ZMODE(1,W3D_Z_LESS
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zless_update
;
724 ZMode
=ZMODE(1,W3D_Z_GEQUAL
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zgequal_update
;
725 ZMode
=ZMODE(1,W3D_Z_LEQUAL
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zlequal_update
;
726 ZMode
=ZMODE(1,W3D_Z_GREATER
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zgreater_update
;
727 ZMode
=ZMODE(1,W3D_Z_NOTEQUAL
);Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_znotequal_update
;
728 ZMode
=ZMODE(1,W3D_Z_EQUAL
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zequal_update
;
729 ZMode
=ZMODE(1,W3D_Z_ALWAYS
); Functions
.Ztest
[ZMode
]=(HOOKEDFUNCTION
)Ztest_zalways_update
;
731 FillMode
=(FALSE
*4 + TRUE
*2 + TRUE
*1 ); Functions
.Fill
[FillMode
]=(HOOKEDFUNCTION
)Fill_Gouraud_Fog
;
732 FillMode
=(FALSE
*4 + TRUE
*2 + FALSE
*1 ); Functions
.Fill
[FillMode
]=(HOOKEDFUNCTION
)Fill_Gouraud
;
733 FillMode
=(FALSE
*4 + FALSE
*2 + TRUE
*1 ); Functions
.Fill
[FillMode
]=(HOOKEDFUNCTION
)Fill_Fog
;
734 FillMode
=(FALSE
*4 + FALSE
*2 + FALSE
*1 ); Functions
.Fill
[FillMode
]=(HOOKEDFUNCTION
)Fill_Flat
;
736 FillMode
=(TRUE
*4 + TRUE
*2 + TRUE
*1 ); Functions
.Fill
[FillMode
]=(HOOKEDFUNCTION
)Fill_Tex_Gouraud_Fog
;
737 FillMode
=(TRUE
*4 + TRUE
*2 + FALSE
*1 ); Functions
.Fill
[FillMode
]=(HOOKEDFUNCTION
)Fill_Tex_Gouraud
;
738 FillMode
=(TRUE
*4 + FALSE
*2 + TRUE
*1 ); Functions
.Fill
[FillMode
]=(HOOKEDFUNCTION
)Fill_Tex_Fog
;
739 FillMode
=(TRUE
*4 + FALSE
*2 + FALSE
*1 ); Functions
.Fill
[FillMode
]=(HOOKEDFUNCTION
)Fill_Tex
;
741 Functions
.Edge
[0]=(HOOKEDFUNCTION
)Edge_Flat
; /* Flat */
742 Functions
.Edge
[1]=(HOOKEDFUNCTION
)Edge_Tex_Gouraud_Fog
; /* Fog */
743 Functions
.Edge
[2]=(HOOKEDFUNCTION
)Edge_Gouraud
; /* Gouraud */
744 Functions
.Edge
[3]=(HOOKEDFUNCTION
)Edge_Tex_Gouraud_Fog
; /* Gouraud_Fog */
745 Functions
.Edge
[4]=(HOOKEDFUNCTION
)Edge_Tex
; /* Tex */
746 Functions
.Edge
[5]=(HOOKEDFUNCTION
)Edge_Tex_Gouraud_Fog
; /* Tex_Fog */
747 Functions
.Edge
[6]=(HOOKEDFUNCTION
)Edge_Tex_Gouraud_Fog
; /* Tex_Gouraud */
748 Functions
.Edge
[7]=(HOOKEDFUNCTION
)Edge_Tex_Gouraud_Fog
; /* Tex_Gouraud_Fog */
750 Functions
.Edge
[ 8]=(HOOKEDFUNCTION
)Edge_Flat
; /* Persp_Flat */
751 Functions
.Edge
[ 9]=(HOOKEDFUNCTION
)Edge_Tex_Gouraud_Fog
; /* Persp_Fog */
752 Functions
.Edge
[10]=(HOOKEDFUNCTION
)Edge_Gouraud
; /* Persp_Gouraud */
753 Functions
.Edge
[11]=(HOOKEDFUNCTION
)Edge_Tex_Gouraud_Fog
; /* Persp_Gouraud_Fog */
754 Functions
.Edge
[12]=(HOOKEDFUNCTION
)Edge_Persp_Tex
; /* Persp_Tex */
755 Functions
.Edge
[13]=(HOOKEDFUNCTION
)Edge_Persp_Tex_Gouraud_Fog
; /* Persp_Tex_Fog */
756 Functions
.Edge
[14]=(HOOKEDFUNCTION
)Edge_Persp_Tex_Gouraud_Fog
; /* Persp_Tex_Gouraud */
757 Functions
.Edge
[15]=(HOOKEDFUNCTION
)Edge_Persp_Tex_Gouraud_Fog
; /* Persp_Tex_Gouraud_Fog*/
759 Functions
.TexEnv
[0 *2+0]=(HOOKEDFUNCTION
)NULL
;
760 Functions
.TexEnv
[W3D_REPLACE
*2+0]=(HOOKEDFUNCTION
)PixelsReplace24
;
761 Functions
.TexEnv
[W3D_REPLACE
*2+1]=(HOOKEDFUNCTION
)PixelsReplace32
;
762 Functions
.TexEnv
[W3D_MODULATE
*2+0]=(HOOKEDFUNCTION
)PixelsModulate24
;
763 Functions
.TexEnv
[W3D_MODULATE
*2+1]=(HOOKEDFUNCTION
)PixelsModulate32
;
764 Functions
.TexEnv
[W3D_DECAL
*2+0]=(HOOKEDFUNCTION
)PixelsDecal24
;
765 Functions
.TexEnv
[W3D_DECAL
*2+1]=(HOOKEDFUNCTION
)PixelsDecal32
;
766 Functions
.TexEnv
[W3D_BLEND
*2+0]=(HOOKEDFUNCTION
)PixelsBlend24
;
767 Functions
.TexEnv
[W3D_BLEND
*2+1]=(HOOKEDFUNCTION
)PixelsBlend32
;
769 Functions
.TexEnv
[W3D_ADD
*2+0]=(HOOKEDFUNCTION
)PixelsAdd24
;
770 Functions
.TexEnv
[W3D_ADD
*2+1]=(HOOKEDFUNCTION
)PixelsAdd32
;
771 Functions
.TexEnv
[W3D_SUB
*2+0]=(HOOKEDFUNCTION
)PixelsSub24
;
772 Functions
.TexEnv
[W3D_SUB
*2+1]=(HOOKEDFUNCTION
)PixelsSub32
;
775 SC
->FunctionWriteImageBuffer
=(HOOKEDFUNCTION
)WriteImageBuffer
;
777 /* default set to "no fast blend function " */
779 Functions
.BlendFast
[n
]=(HOOKEDFUNCTION
)NULL
;
781 Functions
.BlendFast
[W3D_ONE
*16 + W3D_ZERO
]= (HOOKEDFUNCTION
)PixelsOne_Zero32
; /* classic Replace */
782 Functions
.BlendFast
[W3D_SRC_ALPHA
*16 + W3D_ONE_MINUS_SRC_ALPHA
]= (HOOKEDFUNCTION
)PixelsSrcAlpha_OneMinusSrcAlpha32
; /* classic Alpha transparency */
783 Functions
.BlendFast
[W3D_SRC_ALPHA
*16 + W3D_ONE
]= (HOOKEDFUNCTION
)PixelsSrcAlpha_One32
; /* Glxcess' transparency */
784 Functions
.BlendFast
[W3D_ONE
*16 + W3D_ONE
]= (HOOKEDFUNCTION
)PixelsOne_One24
; /* Quake's glow effect */
785 Functions
.BlendFast
[W3D_ZERO
*16 + W3D_SRC_ALPHA
]= (HOOKEDFUNCTION
)PixelsZero_SrcAlpha32
; /* Quake's lightmap effect */
786 Functions
.BlendFast
[W3D_ZERO
*16 + W3D_SRC_COLOR
]= (HOOKEDFUNCTION
)PixelsZero_SrcColor24
; /* Modulate effect */
787 Functions
.BlendFast
[W3D_DST_COLOR
*16 + W3D_ZERO
]= (HOOKEDFUNCTION
)PixelsDstColor_Zero24
; /* modulate effect = same as M */
788 Functions
.BlendFast
[W3D_ZERO
*16 + W3D_ONE_MINUS_SRC_COLOR
]= (HOOKEDFUNCTION
)PixelsZero_OneMinusSrcColor24
; /* Coloring for demo Glxcess */
789 Functions
.BlendFast
[W3D_SRC_ALPHA
*16 + W3D_ONE_MINUS_SRC_COLOR
]= (HOOKEDFUNCTION
)PixelsSrcAlpha_OneMinusSrcColor32
; /* coloring for demo Glxcess */
790 Functions
.BlendFast
[W3D_ONE
*16 + W3D_ONE_MINUS_SRC_ALPHA
]= (HOOKEDFUNCTION
)PixelsOne_OneMinusSrcAlpha32
; /* GlTron transparency */
792 /* v51: fast simple chromatest : color not black */
793 Functions
.BlendFast
[BLENDCHROMA
]= (HOOKEDFUNCTION
)PixelsChroma32fast
;
795 Functions
.BlendFast
[BLENDFASTALPHA
]= (HOOKEDFUNCTION
)PixelsSrcAlpha_OneMinusSrcAlpha32fast
;
799 /* compute the precalculated tables */
806 SC
->Mul8
[Oper
.L
.Index
]=((x
*y
)/255);
808 SC
->Add8
[Oper
.L
.Index
]=x
+y
;
810 SC
->Add8
[Oper
.L
.Index
]=255;
811 SC
->Fil8
[Oper
.L
.Index
]=(x
+y
)/2;
816 /* fragments buffer sizes */
817 SC
->FragBufferDone
=SC
->FragBuffer
;
818 SC
->FragBufferMaxi
=SC
->FragBuffer
+ (FRAGBUFFERSIZE
-MAXSCREEN
-4);
821 #if defined(OS4COMPOSITING)
822 SC
->UseHard
=(Wazp3D
->Renderer
.ON
==2); /* 2= Compositing so will disable soft renderering */
823 if(SC
->UseHard
) COMP3D_Start(SC
);
827 struct HARD3D_context
*HC
=&SC
->HC
;
828 SC
->UseHard
=(Wazp3D
->Renderer
.ON
>=2); /* as 2 mean "use hard" */
831 HC
->UseAntiAlias
= (Wazp3D
->UseAntiImage
.ON
);
832 HC
->UseOverlay
= (Wazp3D
->Renderer
.ON
==3 );
833 HC
->DebugHard
= (Wazp3D
->DebugSC
.ON
==TRUE
);
834 HC
->awin
= Wazp3D
->window
;
835 HARD3D_Start(&SC
->HC
);
838 SC
->Tnb
=0; /* texture number */
840 #if !defined(AMIGA) /* so we are compiling the DLL */
841 Wazp3D
->UseRatioAlpha
.ON
=FALSE
;
842 Wazp3D
->UseAlphaMinMax
.ON
=FALSE
;
843 Wazp3D
->TexMode
.ON
=1; /* we assume that PC cpu is fast enough to enable nice features */
844 Wazp3D
->PerspMode
.ON
=2;
847 SREM(SOFT3D_Start
:OK
)
850 /*=================================================================*/
851 void SOFT3D_SetClipping(APTR sc
,UWORD xmin
,UWORD xmax
,UWORD ymin
,UWORD ymax
)
853 struct SOFT3D_context
*SC
=sc
;
855 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
856 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
857 SFUNCTION(SOFT3D_SetClipping
)
869 if(SC
->UseHard
) HARD3D_SetClipping(&SC
->HC
,xmin
,xmax
,ymin
,ymax
);
872 /*=============================================================*/
873 void SOFT3D_ClearImageBuffer(APTR sc
,UWORD x
,UWORD y
,UWORD large
,UWORD high
,APTR rgba
)
875 struct SOFT3D_context
*SC
=sc
;
877 ULONG
*ptRGBA32
=(ULONG
*)RGBA
;
878 register ULONG RGBA32
=ptRGBA32
[0];
883 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
884 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
885 SFUNCTION(SOFT3D_ClearImageBuffer
)
886 if(SC
->ImageBuffer32
==NULL
) return;
895 ; /* do nothing as the hardware cant use an existing ImageBuffer32 */
897 SREM(ImageBuffer32 present
)
898 I32
=&SC
->ImageBuffer32
[y
*SC
->large
];
900 size
=SC
->large
*high
/8;
904 I32
[0]=0;I32
[1]=0;I32
[2]=0;I32
[3]=0;
905 I32
[4]=0;I32
[5]=0;I32
[6]=0;I32
[7]=0;
911 I32
[0]=RGBA32
;I32
[1]=RGBA32
;I32
[2]=RGBA32
;I32
[3]=RGBA32
;
912 I32
[4]=RGBA32
;I32
[5]=RGBA32
;I32
[6]=RGBA32
;I32
[7]=RGBA32
;
917 /*=============================================================*/
918 void SOFT3D_ClearZBuffer(APTR sc
,float fz
)
920 struct SOFT3D_context
*SC
=sc
;
921 register ZBUFF
*Zbuffer
;
922 register ULONG size
=SC
->high
*SC
->large
/8;
925 register float zresize
=ZRESIZE
;
927 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
928 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
930 SFUNCTION(SOFT3D_ClearZBuffer
)
932 if(SC
->Zbuffer
!=NULL
) /* only happen in software mode */
937 if (z
< MINZ
) z
=MINZ
;
938 if (MAXZ
< z
) z
=MAXZ
;
942 Zbuffer
[0]=z
; Zbuffer
[1]=z
; Zbuffer
[2]=z
; Zbuffer
[3]=z
;
943 Zbuffer
[4]=z
; Zbuffer
[5]=z
; Zbuffer
[6]=z
; Zbuffer
[7]=z
;
949 if(SC
->UseHard
) HARD3D_ClearZBuffer(&SC
->HC
,fz
);
952 /*==========================================================================*/
953 void SOFT3D_ReadZSpan(APTR sc
, UWORD x
, UWORD y
,ULONG n
, APTR z
)
955 struct SOFT3D_context
*SC
=sc
;
956 register ZBUFF
*Zbuffer
;
959 register float zresize
=ZRESIZE
;
962 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
963 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
964 SFUNCTION(SOFT3D_ReadZSpan
)
965 if(SC
->Zbuffer
!=NULL
) /* only happen in software mode */
967 Zbuffer
=SC
->edge1
[y
].L
.ZbufferY
+ x
;
970 fz
=(float)Zbuffer
[i
];
972 dz
[i
]=(W3D_Double
)fz
;
976 if(SC
->UseHard
) HARD3D_ReadZSpan(&SC
->HC
,x
,y
,n
,z
);
979 /*==========================================================================*/
980 void SOFT3D_WriteZSpan(APTR sc
, UWORD x
, UWORD y
,ULONG n
,APTR z
,APTR mask
)
982 struct SOFT3D_context
*SC
=sc
;
983 register ZBUFF
*Zbuffer
;
984 register W3D_Double
*dz
=z
;
986 register float zresize
=ZRESIZE
;
987 register UBYTE
*m
=mask
;
990 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
991 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
992 SFUNCTION(SOFT3D_WriteZSpan
)
993 if(SC
->Zbuffer
!=NULL
) /* only happen in software mode */
995 Zbuffer
=SC
->edge1
[y
].L
.ZbufferY
+ x
;
1000 if (fz
< MINZ
) fz
=MINZ
;
1001 if (MAXZ
< fz
) fz
=MAXZ
;
1002 Zbuffer
[i
]=fz
*zresize
;
1006 if(SC
->UseHard
) HARD3D_WriteZSpan(&SC
->HC
,x
,y
,n
,z
,mask
);
1009 /*=============================================================*/
1010 void SOFT3D_End(APTR sc
)
1012 struct SOFT3D_context
*SC
=sc
;
1014 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
1015 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
1016 SFUNCTION(SOFT3D_End
)
1017 if(SC
==NULL
) return;
1018 if(SC
->ImageBuffer32
!=NULL
)
1020 SREM(Free ImageBuffer32
)
1021 FREEPTR(SC
->ImageBuffer32
);
1024 if(SC
->UseHard
) HARD3D_End(&SC
->HC
);
1026 #if defined(OS4COMPOSITING)
1027 if(SC
->UseHard
) COMP3D_End(SC
);
1031 /*=============================================================*/
1034 #define ADD8(a1,b1,dst) Add.B.b=b1; Add.B.a=a1; dst=Add8[Add.L.Index];
1035 #define MUL8(a1,b1,dst) Mul.B.b=b1; Mul.B.a=a1; dst=Mul8[Mul.L.Index];
1036 #define NEXTADDMUL8(b1,a1,b2,a2,dst) Mul.B.b=b1; Mul2.B.b=b2; dst=Mul8[Mul.L.Index]+Mul8[Mul2.L.Index];
1037 #define FULLADDMUL8(b1,a1,b2,a2,dst) Mul.B.a=a1; Mul2.B.a=a2; NEXTADDMUL8(b1,a1,b2,a2,dst)
1038 #define FOG8X3(fog,dst) Mul.B.a=fog[3]; Mul.B.b=dst[0]; dst[0]=fog[0]+Mul8[Mul.L.Index]; Mul.B.b=dst[1];dst[1]=fog[1]+Mul8[Mul.L.Index]; Mul.B.b=dst[2]; dst[2]=fog[2]+Mul8[Mul.L.Index];
1039 #define FIL8(a1,b1,dst) Fil.B.a=a1; Fil.B.b=b1; dst=Fil8[Fil.L.Index];
1041 #else /* On x86 dont use the precalculated tables = just compute */
1043 #define ADD8(a1,b1,dst) if( ((UWORD)(b1)+(UWORD)(a1)) < 255) dst=((UWORD)(b1)+(UWORD)(a1)); else dst=255;
1044 #define MUL8(a1,b1,dst) dst=( ((UWORD)(b1)*(UWORD)(a1)) /255);
1045 #define NEXTADDMUL8(b1,a1,b2,a2,dst) dst=( ((UWORD)(b1)*(UWORD)(a1)) /255) + ( ((UWORD)(b2)*(UWORD)(a2)) /255);
1046 #define FULLADDMUL8(b1,a1,b2,a2,dst) dst=( ((UWORD)(b1)*(UWORD)(a1)) /255) + ( ((UWORD)(b2)*(UWORD)(a2)) /255);
1047 #define FOG8X3(fog,dst) dst[0]=fog[0]+( ((UWORD)(fog[3])*(UWORD)(dst[0])) /255); dst[1]=fog[1]+( ((UWORD)(fog[3])*(UWORD)(dst[1])) /255); dst[2]=fog[2]+( ((UWORD)(fog[3])*(UWORD)(dst[2])) /255);
1048 #define FIL8(a1,b1,dst) dst=((UWORD)(b1)+(UWORD)(a1))/2;
1051 /*=============================================================*/
1052 /* since v34:new pixels-functions to do multi-pass blending */
1053 /* see OpenGL doc Ct=texture Cf=color Cc=env*/
1055 GL_TEXTURE_ENV_MODE:
1056 GL_REPLACE C = Ct A = At
1057 GL_MODULATE C = Ct * Cf A = At * Af
1058 GL_BLEND C = Cf*(1-Ct) + Cc*Ct A = Af * At
1059 GL_DECAL C = Cf*(1-At) + Ct*At A = Af
1060 f = fragment, t = texture, c = GL_TEXTURE_ENV_COLOR
1061 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,param);
1062 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,param);
1064 /*=============================================================*/
1065 #define CT1R Frag[0].Tex8[0]
1066 #define CT1G Frag[0].Tex8[1]
1067 #define CT1B Frag[0].Tex8[2]
1068 #define AT1 Frag[0].Tex8[3]
1069 #define CF1R Frag[0].ColorRGBA[0]
1070 #define CF1G Frag[0].ColorRGBA[1]
1071 #define CF1B Frag[0].ColorRGBA[2]
1072 #define AF1 Frag[0].ColorRGBA[3]
1074 #define CT2R Frag[1].Tex8[0]
1075 #define CT2G Frag[1].Tex8[1]
1076 #define CT2B Frag[1].Tex8[2]
1077 #define AT2 Frag[1].Tex8[3]
1078 #define CF2R Frag[1].ColorRGBA[0]
1079 #define CF2G Frag[1].ColorRGBA[1]
1080 #define CF2B Frag[1].ColorRGBA[2]
1081 #define AF2 Frag[1].ColorRGBA[3]
1083 #define CCR EnvRGBA[0]
1084 #define CCG EnvRGBA[1]
1085 #define CCB EnvRGBA[2]
1090 /*=============================================================*/
1091 void PixelsTex32ToImage(struct SOFT3D_context
*SC
)
1093 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1094 register ULONG size
=SC
->FragSize2
;
1096 SREM(PixelsTex32ToImage
)
1099 COPYRGBA(Frag
[0].Image8
,Frag
[0].Tex8
);
1100 COPYRGBA(Frag
[1].Image8
,Frag
[1].Tex8
);
1104 /*=============================================================*/
1105 void PixelsTex24ToImage(struct SOFT3D_context
*SC
)
1107 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1108 register ULONG size
=SC
->FragSize2
;
1109 register union rgba3D Color
;
1110 register ULONG
*dst32
;
1112 SREM(PixelsTex24ToImage
)
1113 Color
.B
.RGBA
[3]=ONE
;
1116 Color
.B
.RGBA
[0]=Frag
[0].Tex8
[0];
1117 Color
.B
.RGBA
[1]=Frag
[0].Tex8
[1];
1118 Color
.B
.RGBA
[2]=Frag
[0].Tex8
[2];
1119 dst32
=(ULONG
*)Frag
[0].Image8
;
1120 *dst32
=Color
.L
.RGBA32
;
1122 Color
.B
.RGBA
[0]=Frag
[1].Tex8
[0];
1123 Color
.B
.RGBA
[1]=Frag
[1].Tex8
[1];
1124 Color
.B
.RGBA
[2]=Frag
[1].Tex8
[2];
1125 dst32
=(ULONG
*)Frag
[1].Image8
;
1126 *dst32
=Color
.L
.RGBA32
;
1130 /*=============================================================*/
1131 void PixelsColorToImage(struct SOFT3D_context
*SC
)
1133 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1134 register ULONG size
=SC
->FragSize2
;
1136 SREM(PixelsColorToImage
)
1139 COPYRGBA(Frag
[0].Image8
,Frag
[0].ColorRGBA
);
1140 COPYRGBA(Frag
[1].Image8
,Frag
[1].ColorRGBA
);
1144 /*=============================================================*/
1145 void PixelsTex32ToBuffer(struct SOFT3D_context
*SC
)
1147 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1148 register ULONG size
=SC
->FragSize2
;
1150 SREM(PixelsTex32ToBuffer
)
1153 COPYRGBA(Frag
[0].BufferRGBA
,Frag
[0].Tex8
);
1154 COPYRGBA(Frag
[1].BufferRGBA
,Frag
[1].Tex8
);
1158 /*=============================================================*/
1159 void PixelsTex24ToBuffer(struct SOFT3D_context
*SC
)
1161 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1162 register ULONG size
=SC
->FragSize2
;
1163 register union rgba3D Color
;
1164 register ULONG
*dst32
;
1166 SREM(PixelsTex24ToBuffer
)
1167 Color
.B
.RGBA
[3]=ONE
;
1170 Color
.B
.RGBA
[0]=Frag
[0].Tex8
[0];
1171 Color
.B
.RGBA
[1]=Frag
[0].Tex8
[1];
1172 Color
.B
.RGBA
[2]=Frag
[0].Tex8
[2];
1173 dst32
=(ULONG
*)Frag
[0].BufferRGBA
;
1174 *dst32
=Color
.L
.RGBA32
;
1176 Color
.B
.RGBA
[0]=Frag
[1].Tex8
[0];
1177 Color
.B
.RGBA
[1]=Frag
[1].Tex8
[1];
1178 Color
.B
.RGBA
[2]=Frag
[1].Tex8
[2];
1179 dst32
=(ULONG
*)Frag
[1].BufferRGBA
;
1180 *dst32
=Color
.L
.RGBA32
;
1184 /*=============================================================*/
1185 void PixelsColorToBuffer(struct SOFT3D_context
*SC
)
1187 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1188 register ULONG size
=SC
->FragSize2
;
1190 SREM(PixelsColorToBuffer
)
1193 COPYRGBA(Frag
[0].BufferRGBA
,Frag
[0].ColorRGBA
);
1194 COPYRGBA(Frag
[1].BufferRGBA
,Frag
[1].ColorRGBA
);
1198 /*=============================================================*/
1199 void PixelsReplace24(struct SOFT3D_context
*SC
)
1201 /* replace color=tex (always) */
1202 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1203 register ULONG size
=SC
->FragSize2
;
1204 register union rgba3D Color
;
1205 register ULONG
*dst32
;
1207 SREM(PixelsReplace24
)
1208 Color
.B
.RGBA
[3]=ONE
;
1211 Color
.B
.RGBA
[0]=Frag
[0].Tex8
[0];
1212 Color
.B
.RGBA
[1]=Frag
[0].Tex8
[1];
1213 Color
.B
.RGBA
[2]=Frag
[0].Tex8
[2];
1214 dst32
=(ULONG
*)Frag
[0].ColorRGBA
;
1215 *dst32
=Color
.L
.RGBA32
;
1217 Color
.B
.RGBA
[0]=Frag
[1].Tex8
[0];
1218 Color
.B
.RGBA
[1]=Frag
[1].Tex8
[1];
1219 Color
.B
.RGBA
[2]=Frag
[1].Tex8
[2];
1220 dst32
=(ULONG
*)Frag
[1].ColorRGBA
;
1221 *dst32
=Color
.L
.RGBA32
;
1225 /*=============================================================*/
1226 void PixelsReplace32(struct SOFT3D_context
*SC
)
1228 /* replace color=tex (always) */
1229 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1230 register ULONG size
=SC
->FragSize2
;
1232 SREM(PixelsReplace32
)
1235 COPYRGBA(Frag
[0].ColorRGBA
,Frag
[0].Tex8
);
1236 COPYRGBA(Frag
[1].ColorRGBA
,Frag
[1].Tex8
);
1240 /*=============================================================*/
1241 void PixelsModulate24(struct SOFT3D_context
*SC
)
1243 /* v40: modulate src & dst (always) */
1244 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1245 register ULONG size
=SC
->FragSize2
;
1247 register UBYTE
*Mul8
=SC
->Mul8
;
1248 register union oper3D Mul
;
1252 SREM(PixelsModulate24
)
1255 MUL8(CT1R
,CF1R
,CF1R
)
1256 MUL8(CT1G
,CF1G
,CF1G
)
1257 MUL8(CT1B
,CF1B
,CF1B
)
1259 MUL8(CT2R
,CF2R
,CF2R
)
1260 MUL8(CT2G
,CF2G
,CF2G
)
1261 MUL8(CT2B
,CF2B
,CF2B
)
1265 /*=============================================================*/
1266 void PixelsModulate32(struct SOFT3D_context
*SC
)
1268 /* v40: modulate src & dst (always) */
1269 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1270 register ULONG size
=SC
->FragSize2
;
1272 register UBYTE
*Mul8
=SC
->Mul8
;
1273 register union oper3D Mul
;
1278 SREM(PixelsModulate32
)
1281 MUL8(CT1R
,CF1R
,CF1R
)
1282 MUL8(CT1G
,CF1G
,CF1G
)
1283 MUL8(CT1B
,CF1B
,CF1B
)
1286 MUL8(CT2R
,CF2R
,CF2R
)
1287 MUL8(CT2G
,CF2G
,CF2G
)
1288 MUL8(CT2B
,CF2B
,CF2B
)
1293 /*=============================================================*/
1294 void PixelsDecal24(struct SOFT3D_context
*SC
)
1296 /* v40: decal src & dst (always) */
1297 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1298 register ULONG size
=SC
->FragSize2
;
1315 /*=============================================================*/
1316 void PixelsDecal32(struct SOFT3D_context
*SC
)
1318 /* v40: decal src & dst (always) */
1319 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1320 register ULONG size
=SC
->FragSize2
;
1322 register UBYTE
*Mul8
=SC
->Mul8
;
1323 register union oper3D Mul
;
1324 register union oper3D Mul2
;
1326 Mul
.L
.Index
=Mul2
.L
.Index
=0;
1332 FULLADDMUL8(CT1R
,AT1
,CF1R
,ONE
-AT1
,CF1R
)
1333 FULLADDMUL8(CT1G
,AT1
,CF1G
,ONE
-AT1
,CF1G
)
1334 FULLADDMUL8(CT1B
,AT1
,CF1B
,ONE
-AT1
,CF1B
)
1335 /* AF1=AF1; */ /* alpha from color */
1337 FULLADDMUL8(CT2R
,AT2
,CF2R
,ONE
-AT2
,CF2R
)
1338 FULLADDMUL8(CT2G
,AT2
,CF2G
,ONE
-AT2
,CF2G
)
1339 FULLADDMUL8(CT2B
,AT2
,CF2B
,ONE
-AT2
,CF2B
)
1340 /* AF2=AF2; */ /* alpha from color */
1344 /*=============================================================*/
1345 void PixelsBlend24(struct SOFT3D_context
*SC
)
1347 /* v40: blend src & dst & env (always) */
1348 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1349 register ULONG size
=SC
->FragSize2
;
1350 register UBYTE
*EnvRGBA
=SC
->state
.EnvRGBA
;
1352 register UBYTE
*Mul8
=SC
->Mul8
;
1353 register union oper3D Mul
;
1354 register union oper3D Mul2
;
1356 Mul
.L
.Index
=Mul2
.L
.Index
=0;
1362 FULLADDMUL8(CF1R
,ONE
-CT1R
,CCR
,CT1R
,CF1R
)
1363 FULLADDMUL8(CF1G
,ONE
-CT1G
,CCG
,CT1G
,CF1G
)
1364 FULLADDMUL8(CF1B
,ONE
-CT1B
,CCB
,CT1B
,CF1B
)
1366 FULLADDMUL8(CF2R
,ONE
-CT2R
,CCR
,CT2R
,CF2R
)
1367 FULLADDMUL8(CF2G
,ONE
-CT2G
,CCG
,CT2G
,CF2G
)
1368 FULLADDMUL8(CF2B
,ONE
-CT2B
,CCB
,CT2B
,CF2B
)
1372 /*=============================================================*/
1373 void PixelsBlend32(struct SOFT3D_context
*SC
)
1375 /* v40: blend src & dst & env (always) */
1376 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1377 register ULONG size
=SC
->FragSize2
;
1378 register UBYTE
*EnvRGBA
=SC
->state
.EnvRGBA
;
1380 register UBYTE
*Mul8
=SC
->Mul8
;
1381 register union oper3D Mul
;
1382 register union oper3D Mul2
;
1384 Mul
.L
.Index
=Mul2
.L
.Index
=0;
1390 FULLADDMUL8(CF1R
,ONE
-CT1R
,CCR
,CT1R
,CF1R
)
1391 FULLADDMUL8(CF1G
,ONE
-CT1G
,CCG
,CT1G
,CF1G
)
1392 FULLADDMUL8(CF1B
,ONE
-CT1B
,CCB
,CT1B
,CF1B
)
1395 FULLADDMUL8(CF2R
,ONE
-CT2R
,CCR
,CT2R
,CF2R
)
1396 FULLADDMUL8(CF2G
,ONE
-CT2G
,CCG
,CT2G
,CF2G
)
1397 FULLADDMUL8(CF2B
,ONE
-CT2B
,CCB
,CT2B
,CF2B
)
1402 /*=============================================================*/
1403 void PixelsAdd24(struct SOFT3D_context
*SC
)
1405 /* v50: add src & dst (always) */
1406 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1407 register ULONG size
=SC
->FragSize2
;
1409 register UBYTE
*Add8
=SC
->Add8
;
1410 register union oper3D Add
;
1417 ADD8(CT1R
,CF1R
,CF1R
) /* do color=color+tex */
1418 ADD8(CT1G
,CF1G
,CF1G
)
1419 ADD8(CT1B
,CF1B
,CF1B
)
1421 ADD8(CT2R
,CF2R
,CF2R
)
1422 ADD8(CT2G
,CF2G
,CF2G
)
1423 ADD8(CT2B
,CF2B
,CF2B
)
1427 /*=============================================================*/
1428 void PixelsAdd32(struct SOFT3D_context
*SC
)
1430 /* v50: add src & dst (always) */
1431 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1432 register ULONG size
=SC
->FragSize2
;
1434 register UBYTE
*Add8
=SC
->Add8
;
1435 register union oper3D Add
;
1443 ADD8(CT1R
,CF1R
,CF1R
) /* do color=color+tex */
1444 ADD8(CT1G
,CF1G
,CF1G
)
1445 ADD8(CT1B
,CF1B
,CF1B
)
1448 ADD8(CT2R
,CF2R
,CF2R
)
1449 ADD8(CT2G
,CF2G
,CF2G
)
1450 ADD8(CT2B
,CF2B
,CF2B
)
1455 /*=============================================================*/
1456 void PixelsSub24(struct SOFT3D_context
*SC
)
1458 /* v50: sub src & dst (always) */
1459 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1460 register ULONG size
=SC
->FragSize2
;
1465 if(CF1R
>CT1R
) CF1R
=CF1R
-CT1R
; else CF1R
=0;
1466 if(CF1G
>CT1G
) CF1G
=CF1G
-CT1G
; else CF1G
=0;
1467 if(CF1B
>CT1B
) CF1B
=CF1B
-CT1B
; else CF1B
=0;
1469 if(CF2R
>CT2R
) CF2R
=CF2R
-CT2R
; else CF2R
=0;
1470 if(CF2G
>CT2G
) CF2G
=CF2G
-CT2G
; else CF2G
=0;
1471 if(CF2B
>CT2B
) CF2B
=CF2B
-CT2B
; else CF2B
=0;
1475 /*=============================================================*/
1476 void PixelsSub32(struct SOFT3D_context
*SC
)
1478 /* v50: sub src & dst (always) */
1479 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1480 register ULONG size
=SC
->FragSize2
;
1485 if(CF1R
>CT1R
) CF1R
=CF1R
-CT1R
; else CF1R
=0;
1486 if(CF1G
>CT1G
) CF1G
=CF1G
-CT1G
; else CF1G
=0;
1487 if(CF1B
>CT1B
) CF1B
=CF1B
-CT1B
; else CF1B
=0;
1488 if(AF1
>AT1
) AF1
=AF1
-AT1
; else AF1
=0;
1490 if(CF2R
>CT2R
) CF2R
=CF2R
-CT2R
; else CF2R
=0;
1491 if(CF2G
>CT2G
) CF2G
=CF2G
-CT2G
; else CF2G
=0;
1492 if(CF2B
>CT2B
) CF2B
=CF2B
-CT2B
; else CF2B
=0;
1493 if(AF2
>AT2
) AF2
=AF2
-AT2
; else AF2
=0;
1497 /*=============================================================*/
1498 void PixelsFogToImage(struct SOFT3D_context
*SC
)
1500 /* blend source & dest (always) with a fog color already weigthed to fog A */
1501 /* FogRGBA[3] is set to background transparency against fog level */
1502 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1503 register ULONG size
=SC
->FragSize2
;
1508 register UBYTE
*Mul8
=SC
->Mul8
;
1509 register union oper3D Mul
;
1511 register union oper3D Mul2
;
1517 SREM(PixelsFogToBuffer
)
1520 /* TODO: find why this dont works
1521 FOG8X3(Frag[0].FogRGBA,Frag[0].Image8);
1522 FOG8X3(Frag[1].FogRGBA,Frag[1].Image8);
1524 A
=Frag
[0].FogRGBA
[3];
1525 FULLADDMUL8(SC
->state
.FogRGBA
[0],ONE
-A
,Frag
[0].Image8
[0],A
,Frag
[0].Image8
[0])
1526 FULLADDMUL8(SC
->state
.FogRGBA
[1],ONE
-A
,Frag
[0].Image8
[1],A
,Frag
[0].Image8
[1])
1527 FULLADDMUL8(SC
->state
.FogRGBA
[2],ONE
-A
,Frag
[0].Image8
[2],A
,Frag
[0].Image8
[2])
1528 Frag
[0].Image8
[3]=255;
1530 A
=Frag
[1].FogRGBA
[3];
1531 FULLADDMUL8(SC
->state
.FogRGBA
[0],ONE
-A
,Frag
[1].Image8
[0],A
,Frag
[1].Image8
[0])
1532 FULLADDMUL8(SC
->state
.FogRGBA
[1],ONE
-A
,Frag
[1].Image8
[1],A
,Frag
[1].Image8
[1])
1533 FULLADDMUL8(SC
->state
.FogRGBA
[2],ONE
-A
,Frag
[1].Image8
[2],A
,Frag
[1].Image8
[2])
1534 Frag
[1].Image8
[3]=255;
1539 /*=============================================================*/
1540 void PixelsFogToBuffer(struct SOFT3D_context
*SC
)
1542 /* blend source & dest (always) with a fog color already weigthed to fog A */
1543 /* FogRGBA[3] is set to background transparency against fog level */
1544 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1545 register ULONG size
=SC
->FragSize2
;
1550 register UBYTE
*Mul8
=SC
->Mul8
;
1551 register union oper3D Mul
;
1553 register union oper3D Mul2
;
1559 SREM(PixelsFogToBuffer
)
1562 /* TODO: find why this dont works
1563 FOG8X3(Frag[0].FogRGBA,Frag[0].BufferRGBA);
1564 FOG8X3(Frag[1].FogRGBA,Frag[1].BufferRGBA);
1566 A
=Frag
[0].FogRGBA
[3];
1567 FULLADDMUL8(SC
->state
.FogRGBA
[0],ONE
-A
,Frag
[0].BufferRGBA
[0],A
,Frag
[0].BufferRGBA
[0])
1568 FULLADDMUL8(SC
->state
.FogRGBA
[1],ONE
-A
,Frag
[0].BufferRGBA
[1],A
,Frag
[0].BufferRGBA
[1])
1569 FULLADDMUL8(SC
->state
.FogRGBA
[2],ONE
-A
,Frag
[0].BufferRGBA
[2],A
,Frag
[0].BufferRGBA
[2])
1570 Frag
[0].BufferRGBA
[3]=255;
1572 A
=Frag
[1].FogRGBA
[3];
1573 FULLADDMUL8(SC
->state
.FogRGBA
[0],ONE
-A
,Frag
[1].BufferRGBA
[0],A
,Frag
[1].BufferRGBA
[0])
1574 FULLADDMUL8(SC
->state
.FogRGBA
[1],ONE
-A
,Frag
[1].BufferRGBA
[1],A
,Frag
[1].BufferRGBA
[1])
1575 FULLADDMUL8(SC
->state
.FogRGBA
[2],ONE
-A
,Frag
[1].BufferRGBA
[2],A
,Frag
[1].BufferRGBA
[2])
1576 Frag
[1].BufferRGBA
[3]=255;
1581 /*=============================================================*/
1582 void PixelsSepiaToImage(struct SOFT3D_context
*SC
)
1584 /* colorize in red the pixels */
1585 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1586 register ULONG size
=SC
->FragSize2
;
1589 SREM(PixelsSepiaToImage
)
1592 r
=Frag
[0].Image8
[0]+Frag
[0].Image8
[1]+Frag
[0].Image8
[2];
1593 Frag
[0].Image8
[0]=255;
1595 Frag
[0].Image8
[0]=r
/2;
1596 Frag
[0].Image8
[1]=r
/4;
1597 Frag
[0].Image8
[2]=r
/6;
1599 r
=Frag
[1].Image8
[0]+Frag
[1].Image8
[1]+Frag
[1].Image8
[2];
1600 Frag
[1].Image8
[0]=255;
1602 Frag
[1].Image8
[0]=r
/2;
1603 Frag
[1].Image8
[1]=r
/4;
1604 Frag
[1].Image8
[2]=r
/6;
1608 /*=============================================================*/
1609 void PixelsSepiaToBuffer(struct SOFT3D_context
*SC
)
1611 /* colorize in red the pixels */
1612 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1613 register ULONG size
=SC
->FragSize2
;
1616 SREM(PixelsSepiaToBuffer
)
1619 r
=Frag
[0].BufferRGBA
[0]+Frag
[0].BufferRGBA
[1]+Frag
[0].BufferRGBA
[2];
1620 Frag
[0].BufferRGBA
[0]=255;
1622 Frag
[0].BufferRGBA
[0]=r
/2;
1623 Frag
[0].BufferRGBA
[1]=r
/4;
1624 Frag
[0].BufferRGBA
[2]=r
/6;
1626 r
=Frag
[1].BufferRGBA
[0]+Frag
[1].BufferRGBA
[1]+Frag
[1].BufferRGBA
[2];
1627 Frag
[1].BufferRGBA
[0]=255;
1629 Frag
[1].BufferRGBA
[0]=r
/2;
1630 Frag
[1].BufferRGBA
[1]=r
/4;
1631 Frag
[1].BufferRGBA
[2]=r
/6;
1635 /*=============================================================*/
1636 void PixelsFilterToImage(struct SOFT3D_context
*SC
)
1638 /* colorize in red the pixels */
1639 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1640 register LONG size
=SC
->FragSize2
-4;
1642 register UBYTE
*Fil8
=SC
->Fil8
;
1643 register union oper3D Fil
;
1648 SREM(PixelsFilterToImage
)
1652 if( (Frag
[1].Image8
-Frag
[0].Image8
) <= 4) /* if pixels are contiguous ? TODO: remove this slow test */
1654 FIL8(Frag
[0].Image8
[0],Frag
[1].Image8
[0],Frag
[0].Image8
[0]);
1655 FIL8(Frag
[0].Image8
[1],Frag
[1].Image8
[1],Frag
[0].Image8
[1]);
1656 FIL8(Frag
[0].Image8
[2],Frag
[1].Image8
[2],Frag
[0].Image8
[2]);
1659 if( (Frag
[2].Image8
-Frag
[1].Image8
) <= 4)
1661 FIL8(Frag
[1].Image8
[0],Frag
[2].Image8
[0],Frag
[1].Image8
[0]);
1662 FIL8(Frag
[1].Image8
[1],Frag
[2].Image8
[1],Frag
[1].Image8
[1]);
1663 FIL8(Frag
[1].Image8
[2],Frag
[2].Image8
[2],Frag
[1].Image8
[2]);
1669 /*=============================================================*/
1670 void PixelsFilterToBuffer(struct SOFT3D_context
*SC
)
1672 /* colorize in red the pixels */
1673 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1674 register LONG size
=SC
->FragSize2
-4;
1676 register UBYTE
*Fil8
=SC
->Fil8
;
1677 register union oper3D Fil
;
1682 SREM(PixelsFilterToBuffer
)
1685 if( (Frag
[1].Image8
-Frag
[0].Image8
) <= 4)
1687 FIL8(Frag
[0].BufferRGBA
[0],Frag
[1].BufferRGBA
[0],Frag
[0].BufferRGBA
[0]);
1688 FIL8(Frag
[0].BufferRGBA
[1],Frag
[1].BufferRGBA
[1],Frag
[0].BufferRGBA
[1]);
1689 FIL8(Frag
[0].BufferRGBA
[2],Frag
[1].BufferRGBA
[2],Frag
[0].BufferRGBA
[2]);
1692 if( (Frag
[2].Image8
-Frag
[1].Image8
) <= 4)
1694 FIL8(Frag
[1].BufferRGBA
[0],Frag
[2].BufferRGBA
[0],Frag
[1].BufferRGBA
[0]);
1695 FIL8(Frag
[1].BufferRGBA
[1],Frag
[2].BufferRGBA
[1],Frag
[1].BufferRGBA
[1]);
1696 FIL8(Frag
[1].BufferRGBA
[2],Frag
[2].BufferRGBA
[2],Frag
[1].BufferRGBA
[2]);
1702 /*=============================================================*/
1703 /* define all that to make formulas more easy to read */
1704 #define SRC1 Frag[0].ColorRGBA
1705 #define SRC1R Frag[0].ColorRGBA[0]
1706 #define SRC1G Frag[0].ColorRGBA[1]
1707 #define SRC1B Frag[0].ColorRGBA[2]
1708 #define SRC1A Frag[0].ColorRGBA[3]
1710 #define DST1 Frag[0].BufferRGBA
1711 #define DST1R Frag[0].BufferRGBA[0]
1712 #define DST1G Frag[0].BufferRGBA[1]
1713 #define DST1B Frag[0].BufferRGBA[2]
1714 #define DST1A Frag[0].BufferRGBA[3]
1716 #define TMP1 Frag[0].TmpRGBA
1717 #define TMP1R Frag[0].TmpRGBA[0]
1718 #define TMP1G Frag[0].TmpRGBA[1]
1719 #define TMP1B Frag[0].TmpRGBA[2]
1720 #define TMP1A Frag[0].TmpRGBA[3]
1722 #define SRC2 Frag[1].ColorRGBA
1723 #define SRC2R Frag[1].ColorRGBA[0]
1724 #define SRC2G Frag[1].ColorRGBA[1]
1725 #define SRC2B Frag[1].ColorRGBA[2]
1726 #define SRC2A Frag[1].ColorRGBA[3]
1728 #define DST2 Frag[1].BufferRGBA
1729 #define DST2R Frag[1].BufferRGBA[0]
1730 #define DST2G Frag[1].BufferRGBA[1]
1731 #define DST2B Frag[1].BufferRGBA[2]
1732 #define DST2A Frag[1].BufferRGBA[3]
1734 #define TMP2 Frag[1].TmpRGBA
1735 #define TMP2R Frag[1].TmpRGBA[0]
1736 #define TMP2G Frag[1].TmpRGBA[1]
1737 #define TMP2B Frag[1].TmpRGBA[2]
1738 #define TMP2A Frag[1].TmpRGBA[3]
1740 #define CONSTR SC->state.CurrentRGBA[0]
1741 #define CONSTG SC->state.CurrentRGBA[1]
1742 #define CONSTB SC->state.CurrentRGBA[2]
1743 #define CONSTA SC->state.CurrentRGBA[3]
1745 #define SRCFUNC1(rf,gf,bf,af) MUL8(SRC1R,rf,TMP1R) MUL8(SRC1G,gf,TMP1G) MUL8(SRC1B,bf,TMP1B) MUL8(SRC1A,af,TMP1A)
1746 #define SRCFUNC2(rf,gf,bf,af) MUL8(SRC2R,rf,TMP2R) MUL8(SRC2G,gf,TMP2G) MUL8(SRC2B,bf,TMP2B) MUL8(SRC2A,af,TMP2A)
1747 #define DSTFUNC1(rf,gf,bf,af) MUL8(DST1R,rf,dst) ADD8(TMP1R,dst,DST1R) MUL8(DST1G,gf,dst) ADD8(TMP1G,dst,DST1G) MUL8(DST1B,bf,dst) ADD8(TMP1B,dst,DST1B) MUL8(DST1A,af,dst) ADD8(TMP1A,dst,DST1A)
1748 #define DSTFUNC2(rf,gf,bf,af) MUL8(DST2R,rf,dst) ADD8(TMP2R,dst,DST2R) MUL8(DST2G,gf,dst) ADD8(TMP2G,dst,DST2G) MUL8(DST2B,bf,dst) ADD8(TMP2B,dst,DST2B) MUL8(DST2A,af,dst) ADD8(TMP2A,dst,DST2A)
1749 /*=============================================================*/
1751 srcfunc - The mode for the source pixel:
1756 6 W3D_ONE_MINUS_DST_COLOR
1758 10 W3D_ONE_MINUS_DST_ALPHA
1761 8 W3D_ONE_MINUS_SRC_ALPHA
1763 12 W3D_CONSTANT_COLOR
1764 13 W3D_ONE_MINUS_CONSTANT_COLOR
1765 14 W3D_CONSTANT_ALPHA
1766 15 W3D_ONE_MINUS_CONSTANT_ALPHA
1768 11 W3D_SRC_ALPHA_SATURATE
1770 dstfunc - Mode for the destination:
1775 5 W3D_ONE_MINUS_SRC_COLOR
1777 8 W3D_ONE_MINUS_SRC_ALPHA
1780 10 W3D_ONE_MINUS_DST_ALPHA
1782 12 W3D_CONSTANT_COLOR
1783 13 W3D_ONE_MINUS_CONSTANT_COLOR
1784 14 W3D_CONSTANT_ALPHA
1785 15 W3D_ONE_MINUS_CONSTANT_ALPHA
1788 /*=============================================================*/
1789 void PixelsSrcAlpha_OneMinusSrcAlpha32perfect(struct SOFT3D_context
*SC
)
1791 /* blend source & dest (allways)*/
1792 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1793 register ULONG size
=SC
->FragSize2
;
1795 register UBYTE
*Mul8
=SC
->Mul8
;
1796 register union oper3D Mul
;
1797 register union oper3D Mul2
;
1799 Mul
.L
.Index
=Mul2
.L
.Index
=0;
1802 SREM(PixelsSrcAlpha_OneMinusSrcAlpha32perfect
)
1805 FULLADDMUL8(SRC1R
,SRC1A
,DST1R
,ONE
-SRC1A
,DST1R
)
1806 NEXTADDMUL8(SRC1G
,SRC1A
,DST1G
,ONE
-SRC1A
,DST1G
)
1807 NEXTADDMUL8(SRC1B
,SRC1A
,DST1B
,ONE
-SRC1A
,DST1B
)
1809 FULLADDMUL8(SRC2R
,SRC2A
,DST2R
,ONE
-SRC2A
,DST2R
)
1810 NEXTADDMUL8(SRC2G
,SRC2A
,DST2G
,ONE
-SRC2A
,DST2G
)
1811 NEXTADDMUL8(SRC2B
,SRC2A
,DST2B
,ONE
-SRC2A
,DST2B
)
1815 /*=============================================================*/
1816 void PixelsSrcAlpha_OneMinusSrcAlpha32(struct SOFT3D_context
*SC
)
1818 /* blend source & dest (if source not solid nor transparent)*/
1819 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1820 register ULONG size
=SC
->FragSize2
;
1822 register UBYTE
*Mul8
=SC
->Mul8
;
1823 register union oper3D Mul
;
1824 register union oper3D Mul2
;
1826 Mul
.L
.Index
=Mul2
.L
.Index
=0;
1828 if(!Wazp3D
->UseAlphaMinMax
.ON
)
1829 { PixelsSrcAlpha_OneMinusSrcAlpha32perfect(SC
); return; }
1831 SREM(PixelsSrcAlpha_OneMinusSrcAlpha32
)
1834 if (SRC1A
> MINALPHA
) /* if source visible ? */
1836 if(SRC1A
< MAXALPHA
) /* if source not solid ? */
1838 FULLADDMUL8(SRC1R
,SRC1A
,DST1R
,ONE
-SRC1A
,DST1R
)
1839 NEXTADDMUL8(SRC1G
,SRC1A
,DST1G
,ONE
-SRC1A
,DST1G
)
1840 NEXTADDMUL8(SRC1B
,SRC1A
,DST1B
,ONE
-SRC1A
,DST1B
)
1844 COPYRGBA(Frag
[0].BufferRGBA
,Frag
[0].ColorRGBA
);
1849 if (SRC2A
> MINALPHA
) /* if source visible ? */
1851 if(SRC2A
< MAXALPHA
) /* if source not solid ? */
1853 FULLADDMUL8(SRC2R
,SRC2A
,DST2R
,ONE
-SRC2A
,DST2R
)
1854 NEXTADDMUL8(SRC2G
,SRC2A
,DST2G
,ONE
-SRC2A
,DST2G
)
1855 NEXTADDMUL8(SRC2B
,SRC2A
,DST2B
,ONE
-SRC2A
,DST2B
)
1859 COPYRGBA(Frag
[1].BufferRGBA
,Frag
[1].ColorRGBA
);
1866 /*=============================================================*/
1867 void PixelsChroma32fast(struct SOFT3D_context
*SC
)
1869 /* copy source to dest (if not black)*/
1870 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1871 register ULONG size
=SC
->FragSize2
;
1872 register ULONG black
=((0<<24) + (0<<16) + (0<<8) + 255);
1873 register ULONG
*rgba32
;
1875 SREM(PixelsChroma32fast
)
1878 rgba32
=(ULONG
*)Frag
[0].ColorRGBA
;
1879 if (rgba32
[0] != black
) /* if source visible ? */
1880 COPYRGBA(Frag
[0].BufferRGBA
,Frag
[0].ColorRGBA
);
1882 rgba32
=(ULONG
*)Frag
[1].ColorRGBA
;
1883 if (rgba32
[0] != black
) /* if source visible ? */
1884 COPYRGBA(Frag
[1].BufferRGBA
,Frag
[1].ColorRGBA
);
1888 /*=============================================================*/
1889 void PixelsSrcAlpha_OneMinusSrcAlpha32fast(struct SOFT3D_context
*SC
)
1891 /* copy source to dest (if source not transparent)*/
1892 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1893 register ULONG size
=SC
->FragSize2
;
1895 SREM(PixelsSrcAlpha_OneMinusSrcAlpha32fast
)
1898 if (SRC1A
> MINALPHA
) /* if source visible ? */
1899 COPYRGBA(Frag
[0].BufferRGBA
,Frag
[0].ColorRGBA
);
1901 if (SRC2A
> MINALPHA
) /* if source visible ? */
1902 COPYRGBA(Frag
[1].BufferRGBA
,Frag
[1].ColorRGBA
);
1906 /*=============================================================*/
1907 void PixelsOne_Zero32(struct SOFT3D_context
*SC
)
1909 /* copy source to dest = replace */
1910 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1911 register ULONG size
=SC
->FragSize2
;
1913 SREM(PixelsOne_Zero
)
1916 COPYRGBA(Frag
[0].BufferRGBA
,Frag
[0].ColorRGBA
);
1917 COPYRGBA(Frag
[1].BufferRGBA
,Frag
[1].ColorRGBA
);
1921 /*=============================================================*/
1922 void PixelsSrcAlpha_One32(struct SOFT3D_context
*SC
)
1924 /* v45: for glxcess :-) */
1925 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1926 register ULONG size
=SC
->FragSize2
;
1929 register UBYTE
*Mul8
=SC
->Mul8
;
1930 register UBYTE
*Add8
=SC
->Add8
;
1931 register union oper3D Add
;
1932 register union oper3D Mul
;
1934 Mul
.L
.Index
=Add
.L
.Index
=0;
1937 SREM(PixelsSrcAlpha_One32
)
1940 if (SRC1A
> MINALPHA
) /* if source visible ? */
1942 if(SRC1A
< MAXALPHA
) /* if source not solid ? */
1944 MUL8(SRC1R
,SRC1A
,tmp
) ADD8(tmp
,DST1R
,DST1R
)
1945 MUL8(SRC1G
,SRC1A
,tmp
) ADD8(tmp
,DST1G
,DST1G
)
1946 MUL8(SRC1B
,SRC1A
,tmp
) ADD8(tmp
,DST1B
,DST1B
)
1950 ADD8(SRC1R
,DST1R
,DST1R
)
1951 ADD8(SRC1G
,DST1G
,DST1G
)
1952 ADD8(SRC1B
,DST1B
,DST1B
)
1957 if (SRC2A
> MINALPHA
) /* if source visible ? */
1959 if(SRC2A
< MAXALPHA
) /* if source not solid ? */
1961 MUL8(SRC2R
,SRC2A
,tmp
) ADD8(tmp
,DST2R
,DST2R
)
1962 MUL8(SRC2G
,SRC2A
,tmp
) ADD8(tmp
,DST2G
,DST2G
)
1963 MUL8(SRC2B
,SRC2A
,tmp
) ADD8(tmp
,DST2B
,DST2B
)
1967 ADD8(SRC2R
,DST2R
,DST2R
)
1968 ADD8(SRC2G
,DST2G
,DST2G
)
1969 ADD8(SRC2B
,DST2B
,DST2B
)
1977 /*=============================================================*/
1978 void PixelsOne_OneMinusSrcAlpha32(struct SOFT3D_context
*SC
)
1980 /* v45: for glxcess :-) */
1981 /* v50: this function fixed */
1982 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
1983 register ULONG size
=SC
->FragSize2
;
1987 register UBYTE
*Mul8
=SC
->Mul8
;
1988 register UBYTE
*Add8
=SC
->Add8
;
1989 register union oper3D Add
;
1990 register union oper3D Mul
;
1992 Mul
.L
.Index
=Add
.L
.Index
=0;
1995 SREM(PixelsOne_OneMinusSrcAlpha32
)
1999 if (A
< MAXALPHA
) /* just keep dest unchanged */
2001 if(A
> MINALPHA
) /* if dest not cleaned */
2003 MUL8(DST1R
,A
,tmp
); ADD8(tmp
,SRC1R
,DST1R
);
2004 MUL8(DST1G
,A
,tmp
); ADD8(tmp
,SRC1G
,DST1G
);
2005 MUL8(DST1B
,A
,tmp
); ADD8(tmp
,SRC1B
,DST1B
);
2009 COPYRGBA(Frag
[0].BufferRGBA
,Frag
[0].ColorRGBA
);
2016 if (A
< MAXALPHA
) /* just keep dest unchanged */
2018 if(A
> MINALPHA
) /* if dest not cleaned */
2020 MUL8(DST2R
,A
,tmp
); ADD8(tmp
,SRC2R
,DST2R
);
2021 MUL8(DST2G
,A
,tmp
); ADD8(tmp
,SRC2G
,DST2G
);
2022 MUL8(DST2B
,A
,tmp
); ADD8(tmp
,SRC2B
,DST2B
);
2026 COPYRGBA(Frag
[1].BufferRGBA
,Frag
[0].ColorRGBA
);
2036 /*=============================================================*/
2037 void PixelsOne_One24(struct SOFT3D_context
*SC
)
2039 /* v41: add saturate src & dst (allways) */
2040 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2041 register ULONG size
=SC
->FragSize2
;
2042 register union rgba3D Tmp1
;
2043 register union rgba3D Tmp2
;
2045 register UBYTE
*Add8
=SC
->Add8
;
2046 register union oper3D Add
;
2050 SREM(PixelsOne_One24
)
2053 ULONG
*_dst1
= (ULONG
*)DST1
;
2054 ULONG
*_dst2
= (ULONG
*)DST2
;
2055 Tmp1
.L
.RGBA32
=*_dst1
;
2056 Tmp2
.L
.RGBA32
=*_dst2
;
2058 ADD8(SRC1R
,Tmp1
.B
.RGBA
[0],Tmp1
.B
.RGBA
[0])
2059 ADD8(SRC1G
,Tmp1
.B
.RGBA
[1],Tmp1
.B
.RGBA
[1])
2060 ADD8(SRC1B
,Tmp1
.B
.RGBA
[2],Tmp1
.B
.RGBA
[2])
2062 ADD8(SRC2R
,Tmp2
.B
.RGBA
[0],Tmp2
.B
.RGBA
[0])
2063 ADD8(SRC2G
,Tmp2
.B
.RGBA
[1],Tmp2
.B
.RGBA
[1])
2064 ADD8(SRC2B
,Tmp2
.B
.RGBA
[2],Tmp2
.B
.RGBA
[2])
2066 *_dst1
=Tmp1
.L
.RGBA32
;
2067 *_dst2
=Tmp2
.L
.RGBA32
;
2071 /*=============================================================*/
2072 void PixelsZero_SrcAlpha32(struct SOFT3D_context
*SC
)
2074 /* v41: alpha-modulate dst (allways) */
2075 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2076 register ULONG size
=SC
->FragSize2
;
2078 register UBYTE
*Mul8
=SC
->Mul8
;
2079 register union oper3D Mul
;
2084 SREM(PixelsZero_SrcAlpha32
)
2087 MUL8(SRC1A
,DST1R
,DST1R
)
2088 MUL8(SRC1A
,DST1G
,DST1G
)
2089 MUL8(SRC1A
,DST1B
,DST1B
)
2091 MUL8(SRC2A
,DST2R
,DST2R
)
2092 MUL8(SRC2A
,DST2G
,DST2G
)
2093 MUL8(SRC2A
,DST2B
,DST2B
)
2097 /*=============================================================*/
2098 void PixelsZero_SrcColor24(struct SOFT3D_context
*SC
)
2100 /* v45: color-modulate dst (allways) */
2101 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2102 register ULONG size
=SC
->FragSize2
;
2104 register UBYTE
*Mul8
=SC
->Mul8
;
2105 register union oper3D Mul
;
2110 SREM(PixelsZero_SrcColor24
)
2113 MUL8(SRC1R
,DST1R
,DST1R
)
2114 MUL8(SRC1G
,DST1G
,DST1G
)
2115 MUL8(SRC1B
,DST1B
,DST1B
)
2117 MUL8(SRC2R
,DST2R
,DST2R
)
2118 MUL8(SRC2G
,DST2G
,DST2G
)
2119 MUL8(SRC2B
,DST2B
,DST2B
)
2123 /*=============================================================*/
2124 void PixelsZero_OneMinusSrcColor24(struct SOFT3D_context
*SC
)
2126 /* v45: for glxcess :-) */
2127 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2128 register ULONG size
=SC
->FragSize2
;
2130 register UBYTE
*Mul8
=SC
->Mul8
;
2131 register union oper3D Mul
;
2136 SREM(PixelsZero_OneMinusSrcColor24
)
2139 MUL8(ONE
-SRC1R
,DST1R
,DST1R
)
2140 MUL8(ONE
-SRC1G
,DST1G
,DST1G
)
2141 MUL8(ONE
-SRC1B
,DST1B
,DST1B
)
2143 MUL8(ONE
-SRC2R
,DST2R
,DST2R
)
2144 MUL8(ONE
-SRC2G
,DST2G
,DST2G
)
2145 MUL8(ONE
-SRC2B
,DST2B
,DST2B
)
2149 /*=============================================================*/
2150 void PixelsSrcAlpha_OneMinusSrcColor32(struct SOFT3D_context
*SC
)
2152 /* v45: for glxcess :-) */
2153 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2154 register ULONG size
=SC
->FragSize2
;
2156 register UBYTE
*Mul8
=SC
->Mul8
;
2157 register union oper3D Mul
;
2158 register union oper3D Mul2
;
2160 Mul
.L
.Index
=Mul2
.L
.Index
=0;
2163 SREM(PixelsSrcAlpha_OneMinusSrcColor32
)
2166 FULLADDMUL8(SRC1R
,SRC1A
,DST1R
,ONE
-SRC1R
,DST1R
)
2167 FULLADDMUL8(SRC1G
,SRC1A
,DST1G
,ONE
-SRC1G
,DST1G
)
2168 FULLADDMUL8(SRC1B
,SRC1A
,DST1B
,ONE
-SRC1B
,DST1B
)
2170 FULLADDMUL8(SRC2R
,SRC2A
,DST2R
,ONE
-SRC2R
,DST2R
)
2171 FULLADDMUL8(SRC2G
,SRC2A
,DST2G
,ONE
-SRC2G
,DST2G
)
2172 FULLADDMUL8(SRC2B
,SRC2A
,DST2B
,ONE
-SRC2B
,DST2B
)
2176 /*=============================================================*/
2177 void PixelsDstColor_Zero24(struct SOFT3D_context
*SC
)
2179 SREM(PixelsDstColor_Zero24
)
2180 PixelsZero_SrcColor24(SC
);
2182 /*=============================================================*/
2183 void PixelsBlendFunctionAll(struct SOFT3D_context
*SC
)
2185 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2186 register ULONG size
;
2188 UBYTE ZeroRGBA
[]={0,0,0,0};
2189 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
2193 register UBYTE
*Mul8
=SC
->Mul8
;
2194 register UBYTE
*Add8
=SC
->Add8
;
2195 register union oper3D Add
;
2196 register union oper3D Mul
;
2198 Mul
.L
.Index
=Add
.L
.Index
=0;
2201 SREM(PixelsBlendFunctionAll
)
2202 if(SC
->FunctionBlendFast
==NULL
)
2203 if(Wazp3D
->DebugBlendFunction
.ON
)
2205 PrintST(SC
->state
.ST
);
2206 Libprintf("use slow BlendFunction(Src:%ld,Dst%ld)\n",(ULONG
)SC
->SrcFunc
,(ULONG
)SC
->DstFunc
);
2210 /* store Image to Buffer ? */
2211 if(SC
->ImageBuffer32
!=NULL
)
2214 Frag
=SC
->FragBuffer
;
2217 COPYRGBA(Frag
[0].BufferRGBA
,Frag
[0].Image8
);
2218 COPYRGBA(Frag
[1].BufferRGBA
,Frag
[1].Image8
);
2223 if(SC
->FunctionBlendFast
!=NULL
)
2225 SC
->FunctionBlendFast(SC
);
2230 Frag
=SC
->FragBuffer
;
2232 /* Step1: do Src Function to TmpRGBA */
2239 COPYRGBA(Frag
[0].TmpRGBA
,ZeroRGBA
);
2240 COPYRGBA(Frag
[1].TmpRGBA
,ZeroRGBA
);
2248 COPYRGBA(Frag
[0].TmpRGBA
,SRC1
); /* ONE x SRC1 = SRC1 */
2249 COPYRGBA(Frag
[1].TmpRGBA
,SRC2
);
2257 SRCFUNC1(DST1R
,DST1G
,DST1B
,DST1A
)
2258 SRCFUNC2(DST2R
,DST2G
,DST2B
,DST2A
)
2263 case W3D_ONE_MINUS_DST_COLOR
:
2266 SRCFUNC1(ONE
-DST1R
,ONE
-DST1G
,ONE
-DST1B
,ONE
-DST1A
)
2267 SRCFUNC2(ONE
-DST2R
,ONE
-DST2G
,ONE
-DST2B
,ONE
-DST2A
)
2275 SRCFUNC1(SRC1A
,SRC1A
,SRC1A
,SRC1A
)
2276 SRCFUNC2(SRC2A
,SRC2A
,SRC2A
,SRC2A
)
2281 case W3D_ONE_MINUS_SRC_ALPHA
:
2284 SRCFUNC1(ONE
-SRC1A
,ONE
-SRC1A
,ONE
-SRC1A
,ONE
-SRC1A
)
2285 SRCFUNC2(ONE
-SRC2A
,ONE
-SRC2A
,ONE
-SRC2A
,ONE
-SRC2A
)
2293 SRCFUNC1(DST1A
,DST1A
,DST1A
,DST1A
)
2294 SRCFUNC2(DST2A
,DST2A
,DST2A
,DST2A
)
2299 case W3D_ONE_MINUS_DST_ALPHA
:
2302 SRCFUNC1(ONE
-DST1A
,ONE
-DST1A
,ONE
-DST1A
,ONE
-DST1A
)
2303 SRCFUNC2(ONE
-DST2A
,ONE
-DST2A
,ONE
-DST2A
,ONE
-DST2A
)
2308 case W3D_CONSTANT_COLOR
:
2311 SRCFUNC1(CONSTR
,CONSTG
,CONSTB
,CONSTA
)
2312 SRCFUNC2(CONSTR
,CONSTG
,CONSTB
,CONSTA
)
2317 case W3D_ONE_MINUS_CONSTANT_COLOR
:
2320 SRCFUNC1(ONE
-CONSTR
,ONE
-CONSTG
,ONE
-CONSTB
,ONE
-CONSTA
)
2321 SRCFUNC2(ONE
-CONSTR
,ONE
-CONSTG
,ONE
-CONSTB
,ONE
-CONSTA
)
2326 case W3D_CONSTANT_ALPHA
:
2329 SRCFUNC1(CONSTA
,CONSTA
,CONSTA
,CONSTA
)
2330 SRCFUNC2(CONSTA
,CONSTA
,CONSTA
,CONSTA
)
2335 case W3D_ONE_MINUS_CONSTANT_ALPHA
:
2338 SRCFUNC1(ONE
-CONSTA
,ONE
-CONSTA
,ONE
-CONSTA
,ONE
-CONSTA
)
2339 SRCFUNC2(ONE
-CONSTA
,ONE
-CONSTA
,ONE
-CONSTA
,ONE
-CONSTA
)
2344 case W3D_SRC_ALPHA_SATURATE
:
2347 i
= MIN (SRC1A
,ONE
- DST1A
) ; /* v47: OpenGL compliant */
2349 i
= MIN (SRC2A
,ONE
- DST2A
) ;
2356 /* Step2: do Dst Function from TmpRGBA */
2358 Frag
=SC
->FragBuffer
;
2365 COPYRGBA(Frag
[0].BufferRGBA
,Frag
[0].TmpRGBA
);
2366 COPYRGBA(Frag
[1].BufferRGBA
,Frag
[1].TmpRGBA
);
2374 ADD8(TMP1R
,DST1R
,DST1R
) ADD8(TMP1G
,DST1G
,DST1G
) ADD8(TMP1B
,DST1B
,DST1B
) ADD8(TMP1A
,DST1A
,DST1A
)
2375 ADD8(TMP2R
,DST2R
,DST2R
) ADD8(TMP2G
,DST2G
,DST2G
) ADD8(TMP2B
,DST2B
,DST2B
) ADD8(TMP2A
,DST2A
,DST2A
)
2383 DSTFUNC1(SRC1R
,SRC1G
,SRC1B
,SRC1A
)
2384 DSTFUNC2(SRC2R
,SRC2G
,SRC2B
,SRC2A
)
2389 case W3D_ONE_MINUS_SRC_COLOR
:
2392 DSTFUNC1(ONE
-SRC1R
,ONE
-SRC1G
,ONE
-SRC1B
,ONE
-SRC1A
)
2393 DSTFUNC2(ONE
-SRC2R
,ONE
-SRC2G
,ONE
-SRC2B
,ONE
-SRC2A
)
2401 DSTFUNC1(DST1A
,DST1A
,DST1A
,DST1A
)
2402 DSTFUNC2(DST2A
,DST2A
,DST2A
,DST2A
)
2407 case W3D_ONE_MINUS_DST_ALPHA
:
2410 DSTFUNC1(ONE
-DST1A
,ONE
-DST1A
,ONE
-DST1A
,ONE
-DST1A
)
2411 DSTFUNC2(ONE
-DST2A
,ONE
-DST2A
,ONE
-DST2A
,ONE
-DST2A
)
2419 DSTFUNC1(SRC1A
,SRC1A
,SRC1A
,SRC1A
)
2420 DSTFUNC2(SRC2A
,SRC2A
,SRC2A
,SRC2A
)
2425 case W3D_ONE_MINUS_SRC_ALPHA
:
2428 DSTFUNC1(ONE
-SRC1A
,ONE
-SRC1A
,ONE
-SRC1A
,ONE
-SRC1A
)
2429 DSTFUNC2(ONE
-SRC2A
,ONE
-SRC2A
,ONE
-SRC2A
,ONE
-SRC2A
)
2434 case W3D_CONSTANT_COLOR
:
2437 DSTFUNC1(CONSTR
,CONSTG
,CONSTB
,CONSTA
)
2438 DSTFUNC2(CONSTR
,CONSTG
,CONSTB
,CONSTA
)
2443 case W3D_ONE_MINUS_CONSTANT_COLOR
:
2446 DSTFUNC1(ONE
-CONSTR
,ONE
-CONSTG
,ONE
-CONSTB
,ONE
-CONSTA
)
2447 DSTFUNC2(ONE
-CONSTR
,ONE
-CONSTG
,ONE
-CONSTB
,ONE
-CONSTA
)
2452 case W3D_CONSTANT_ALPHA
:
2455 DSTFUNC1(CONSTA
,CONSTA
,CONSTA
,CONSTA
)
2456 DSTFUNC2(CONSTA
,CONSTA
,CONSTA
,CONSTA
)
2461 case W3D_ONE_MINUS_CONSTANT_ALPHA
:
2464 DSTFUNC1(ONE
-CONSTA
,ONE
-CONSTA
,ONE
-CONSTA
,ONE
-CONSTA
)
2465 DSTFUNC2(ONE
-CONSTA
,ONE
-CONSTA
,ONE
-CONSTA
,ONE
-CONSTA
)
2473 /* store the buffer to image8 ? */
2474 if(SC
->ImageBuffer32
!=NULL
)
2477 Frag
=SC
->FragBuffer
;
2480 COPYRGBA(Frag
[0].Image8
,Frag
[0].BufferRGBA
);
2481 COPYRGBA(Frag
[1].Image8
,Frag
[1].BufferRGBA
);
2487 /*=============================================================*/
2488 /* v52: Optimized 32 bits PixelsIn/Out */
2489 /*=============================================================*/
2491 static inline void SetCOLOR32(APTR dst
, ULONG color
)
2493 ULONG
*_dst
= (ULONG
*)dst
;
2497 static inline ULONG
COLOR32(APTR src
)
2499 ULONG
*_src
= (ULONG
*)src
;
2503 /*=============================================================*/
2504 void PixelsInBGRA(struct SOFT3D_context
*SC
)
2506 /* Convert BGRA -> buffer */
2507 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2508 register ULONG size
=SC
->FragSize2
;
2509 register union rgba3D Color0
;
2510 register union rgba3D Color1
;
2511 register UBYTE temp
;
2515 Color0
.L
.RGBA32
=COLOR32(Frag
[0].Image8
);
2516 Color1
.L
.RGBA32
=COLOR32(Frag
[1].Image8
);
2518 SWAP(Color0
.B
.RGBA
[0],Color0
.B
.RGBA
[2]);
2519 SWAP(Color1
.B
.RGBA
[0],Color1
.B
.RGBA
[2]);
2521 SetCOLOR32(Frag
[0].BufferRGBA
, Color0
.L
.RGBA32
);
2522 SetCOLOR32(Frag
[1].BufferRGBA
, Color1
.L
.RGBA32
);
2526 /*=============================================================*/
2527 void PixelsInARGB(struct SOFT3D_context
*SC
)
2529 /* Convert ARGB -> buffer */
2530 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2531 register ULONG size
=SC
->FragSize2
;
2532 register union rgba3D Color0
;
2533 register union rgba3D Color1
;
2537 Color0
.L
.RGBA32
=COLOR32(Frag
[0].Image8
);
2538 Color1
.L
.RGBA32
=COLOR32(Frag
[1].Image8
);
2540 Color0
.L
.RGBA32
=(Color0
.B
.RGBA
[0]+(Color0
.L
.RGBA32
<<8));
2541 Color1
.L
.RGBA32
=(Color1
.B
.RGBA
[0]+(Color1
.L
.RGBA32
<<8));
2543 SetCOLOR32(Frag
[0].BufferRGBA
, Color0
.L
.RGBA32
);
2544 SetCOLOR32(Frag
[1].BufferRGBA
, Color1
.L
.RGBA32
);
2548 /*=============================================================*/
2549 void PixelsInABGR(struct SOFT3D_context
*SC
)
2551 /* Convert ABGR -> buffer */
2552 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2553 register ULONG size
=SC
->FragSize2
;
2554 register union rgba3D Color0
;
2555 register union rgba3D Color1
;
2556 register UBYTE temp
;
2560 Color0
.L
.RGBA32
=COLOR32(Frag
[0].Image8
);
2561 Color1
.L
.RGBA32
=COLOR32(Frag
[1].Image8
);
2563 SWAP(Color0
.B
.RGBA
[0],Color0
.B
.RGBA
[3]);
2564 SWAP(Color0
.B
.RGBA
[1],Color0
.B
.RGBA
[2]);
2566 SWAP(Color1
.B
.RGBA
[0],Color1
.B
.RGBA
[3]);
2567 SWAP(Color1
.B
.RGBA
[1],Color1
.B
.RGBA
[2]);
2569 SetCOLOR32(Frag
[0].BufferRGBA
, Color0
.L
.RGBA32
);
2570 SetCOLOR32(Frag
[1].BufferRGBA
, Color1
.L
.RGBA32
);
2574 /*=============================================================*/
2575 /*=============================================================*/
2576 void PixelsOutBGRA_Flat(struct SOFT3D_context
*SC
)
2578 /* Convert BGRA <- buffer */
2579 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2580 register ULONG size4
=SC
->FragSize2
/2;
2581 register union rgba3D Color0
;
2582 register UBYTE temp
;
2584 Color0
.L
.RGBA32
=COLOR32(Frag
[0].BufferRGBA
);
2585 SWAP(Color0
.B
.RGBA
[0],Color0
.B
.RGBA
[2]);
2589 SetCOLOR32(Frag
[0].Image8
, Color0
.L
.RGBA32
);
2590 SetCOLOR32(Frag
[1].Image8
, Color0
.L
.RGBA32
);
2591 SetCOLOR32(Frag
[2].Image8
, Color0
.L
.RGBA32
);
2592 SetCOLOR32(Frag
[3].Image8
, Color0
.L
.RGBA32
);
2596 /*=============================================================*/
2597 void PixelsOutARGB_Flat(struct SOFT3D_context
*SC
)
2599 /* Convert ARGB <- buffer */
2600 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2601 register ULONG size4
=SC
->FragSize2
/2;
2602 register union rgba3D Color0
;
2604 Color0
.L
.RGBA32
=COLOR32(Frag
[0].BufferRGBA
);
2605 Color0
.L
.RGBA32
=((Color0
.B
.RGBA
[3]<<24)+(Color0
.L
.RGBA32
>>8));
2609 SetCOLOR32(Frag
[0].Image8
, Color0
.L
.RGBA32
);
2610 SetCOLOR32(Frag
[1].Image8
, Color0
.L
.RGBA32
);
2611 SetCOLOR32(Frag
[2].Image8
, Color0
.L
.RGBA32
);
2612 SetCOLOR32(Frag
[3].Image8
, Color0
.L
.RGBA32
);
2616 /*=============================================================*/
2617 void PixelsOutABGR_Flat(struct SOFT3D_context
*SC
)
2619 /* Convert ABGR <- buffer */
2620 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2621 register ULONG size4
=SC
->FragSize2
/2;
2622 register union rgba3D Color0
;
2623 register UBYTE temp
;
2625 Color0
.L
.RGBA32
=COLOR32(Frag
[0].BufferRGBA
);
2626 SWAP(Color0
.B
.RGBA
[0],Color0
.B
.RGBA
[3]);
2627 SWAP(Color0
.B
.RGBA
[1],Color0
.B
.RGBA
[2]);
2631 SetCOLOR32(Frag
[0].Image8
, Color0
.L
.RGBA32
);
2632 SetCOLOR32(Frag
[1].Image8
, Color0
.L
.RGBA32
);
2633 SetCOLOR32(Frag
[2].Image8
, Color0
.L
.RGBA32
);
2634 SetCOLOR32(Frag
[3].Image8
, Color0
.L
.RGBA32
);
2638 /*=============================================================*/
2639 void PixelsOutBGRA(struct SOFT3D_context
*SC
)
2641 /* Convert BGRA <- buffer */
2642 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2643 register ULONG size
=SC
->FragSize2
;
2644 register union rgba3D Color0
;
2645 register union rgba3D Color1
;
2646 register UBYTE temp
;
2650 Color0
.L
.RGBA32
=COLOR32(Frag
[0].BufferRGBA
);
2651 Color1
.L
.RGBA32
=COLOR32(Frag
[1].BufferRGBA
);
2653 SWAP(Color0
.B
.RGBA
[0],Color0
.B
.RGBA
[2]);
2654 SWAP(Color1
.B
.RGBA
[0],Color1
.B
.RGBA
[2]);
2656 SetCOLOR32(Frag
[0].Image8
, Color0
.L
.RGBA32
);
2657 SetCOLOR32(Frag
[1].Image8
, Color1
.L
.RGBA32
);
2661 /*=============================================================*/
2662 void PixelsOutARGB(struct SOFT3D_context
*SC
)
2664 /* Convert ARGB <- buffer */
2665 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2666 register ULONG size
=SC
->FragSize2
;
2667 register union rgba3D Color0
;
2668 register union rgba3D Color1
;
2672 Color0
.L
.RGBA32
=COLOR32(Frag
[0].BufferRGBA
);
2673 Color1
.L
.RGBA32
=COLOR32(Frag
[1].BufferRGBA
);
2675 Color0
.L
.RGBA32
=((Color0
.B
.RGBA
[3]<<24)+(Color0
.L
.RGBA32
>>8));
2676 Color1
.L
.RGBA32
=((Color1
.B
.RGBA
[3]<<24)+(Color1
.L
.RGBA32
>>8));
2678 SetCOLOR32(Frag
[0].Image8
, Color0
.L
.RGBA32
);
2679 SetCOLOR32(Frag
[1].Image8
, Color1
.L
.RGBA32
);
2683 /*=============================================================*/
2684 void PixelsOutABGR(struct SOFT3D_context
*SC
)
2686 /* Convert ABGR <- buffer */
2687 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2688 register ULONG size
=SC
->FragSize2
;
2689 register union rgba3D Color0
;
2690 register union rgba3D Color1
;
2691 register UBYTE temp
;
2695 Color0
.L
.RGBA32
=COLOR32(Frag
[0].BufferRGBA
);
2696 Color1
.L
.RGBA32
=COLOR32(Frag
[1].BufferRGBA
);
2698 SWAP(Color0
.B
.RGBA
[0],Color0
.B
.RGBA
[3]);
2699 SWAP(Color0
.B
.RGBA
[1],Color0
.B
.RGBA
[2]);
2701 SWAP(Color1
.B
.RGBA
[0],Color1
.B
.RGBA
[3]);
2702 SWAP(Color1
.B
.RGBA
[1],Color1
.B
.RGBA
[2]);
2704 SetCOLOR32(Frag
[0].Image8
, Color0
.L
.RGBA32
);
2705 SetCOLOR32(Frag
[1].Image8
, Color1
.L
.RGBA32
);
2709 /*=============================================================*/
2710 void PixelsInRGBA(struct SOFT3D_context
*SC
)
2712 /* Convert RGBA -> buffer */
2713 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2714 register ULONG size4
=SC
->FragSize2
/2;
2718 COPYRGBA(Frag
[0].BufferRGBA
,Frag
[0].Image8
);
2719 COPYRGBA(Frag
[1].BufferRGBA
,Frag
[1].Image8
);
2720 COPYRGBA(Frag
[2].BufferRGBA
,Frag
[0].Image8
);
2721 COPYRGBA(Frag
[3].BufferRGBA
,Frag
[1].Image8
);
2726 /*=============================================================*/
2727 void PixelsOutRGBA_Flat(struct SOFT3D_context
*SC
)
2729 /* Convert buffer -> RGBA */
2730 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2731 register ULONG size4
=SC
->FragSize2
/2;
2732 register union rgba3D Color0
;
2734 Color0
.L
.RGBA32
=COLOR32(Frag
[0].BufferRGBA
);
2737 SetCOLOR32(Frag
[0].Image8
, Color0
.L
.RGBA32
);
2738 SetCOLOR32(Frag
[1].Image8
, Color0
.L
.RGBA32
);
2739 SetCOLOR32(Frag
[2].Image8
, Color0
.L
.RGBA32
);
2740 SetCOLOR32(Frag
[3].Image8
, Color0
.L
.RGBA32
);
2745 /*=============================================================*/
2746 void PixelsOutRGBA(struct SOFT3D_context
*SC
)
2748 /* Convert buffer -> RGBA */
2749 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2750 register ULONG size
=SC
->FragSize2
;
2754 COPYRGBA(Frag
[0].Image8
,Frag
[0].BufferRGBA
);
2755 COPYRGBA(Frag
[1].Image8
,Frag
[1].BufferRGBA
);
2760 /*=============================================================*/
2761 void PixelsOutBGRAfromtex24(struct SOFT3D_context
*SC
)
2763 /* patch suggestion from "Cosmos" : */
2764 /* For a simple prog like CoW3D dont use pipe-line but write tex directly to the BGRA bitmap */
2765 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2766 register ULONG size
=SC
->FragSize2
;
2767 register union rgba3D Color0
;
2768 register union rgba3D Color1
;
2771 Color0
.B
.RGBA
[3]=Color1
.B
.RGBA
[3]=ONE
;
2774 Color0
.B
.RGBA
[2]=Frag
[0].Tex8
[0];
2775 Color0
.B
.RGBA
[1]=Frag
[0].Tex8
[1];
2776 Color0
.B
.RGBA
[0]=Frag
[0].Tex8
[2];
2778 Color1
.B
.RGBA
[2]=Frag
[1].Tex8
[0];
2779 Color1
.B
.RGBA
[1]=Frag
[1].Tex8
[1];
2780 Color1
.B
.RGBA
[0]=Frag
[1].Tex8
[2];
2782 SetCOLOR32(Frag
[0].Image8
, Color0
.L
.RGBA32
);
2783 SetCOLOR32(Frag
[1].Image8
, Color1
.L
.RGBA32
);
2787 /*=============================================================*/
2788 void PixelsOutARGBfromtex24(struct SOFT3D_context
*SC
)
2790 /* patch suggestion from "Cosmos" : */
2791 /* For a simple prog like CoW3D dont use pipe-line but write tex directly to the ARGB bitmap */
2792 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2793 register ULONG size
=SC
->FragSize2
;
2794 register union rgba3D Color0
;
2795 register union rgba3D Color1
;
2798 Color0
.B
.RGBA
[0]=Color1
.B
.RGBA
[0]=ONE
;
2801 Color0
.B
.RGBA
[1]=Frag
[0].Tex8
[0];
2802 Color0
.B
.RGBA
[2]=Frag
[0].Tex8
[1];
2803 Color0
.B
.RGBA
[3]=Frag
[0].Tex8
[2];
2805 Color1
.B
.RGBA
[1]=Frag
[1].Tex8
[0];
2806 Color1
.B
.RGBA
[2]=Frag
[1].Tex8
[1];
2807 Color1
.B
.RGBA
[3]=Frag
[1].Tex8
[2];
2809 SetCOLOR32(Frag
[0].Image8
, Color0
.L
.RGBA32
);
2810 SetCOLOR32(Frag
[1].Image8
, Color1
.L
.RGBA32
);
2814 /*=============================================================*/
2815 /* End of 32 bits functions */
2816 /*=============================================================*/
2817 void PixelsInRGB(struct SOFT3D_context
*SC
)
2819 /* Convert RGB -> buffer */
2820 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2821 register ULONG size
=SC
->FragSize2
;
2825 Frag
[0].BufferRGBA
[0]=Frag
[0].Image8
[0];
2826 Frag
[0].BufferRGBA
[1]=Frag
[0].Image8
[1];
2827 Frag
[0].BufferRGBA
[2]=Frag
[0].Image8
[2];
2828 Frag
[0].BufferRGBA
[3]=ONE
;
2830 Frag
[1].BufferRGBA
[0]=Frag
[1].Image8
[0];
2831 Frag
[1].BufferRGBA
[1]=Frag
[1].Image8
[1];
2832 Frag
[1].BufferRGBA
[2]=Frag
[1].Image8
[2];
2833 Frag
[1].BufferRGBA
[3]=ONE
;
2838 /*=============================================================*/
2839 void PixelsOutRGB(struct SOFT3D_context
*SC
)
2841 /* Convert buffer -> RGB */
2842 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2843 register ULONG size
=SC
->FragSize2
;
2847 Frag
[0].Image8
[0]=Frag
[0].BufferRGBA
[0];
2848 Frag
[0].Image8
[1]=Frag
[0].BufferRGBA
[1];
2849 Frag
[0].Image8
[2]=Frag
[0].BufferRGBA
[2];
2851 Frag
[1].Image8
[0]=Frag
[1].BufferRGBA
[0];
2852 Frag
[1].Image8
[1]=Frag
[1].BufferRGBA
[1];
2853 Frag
[1].Image8
[2]=Frag
[1].BufferRGBA
[2];
2858 /*=============================================================*/
2859 void PixelsInBGR(struct SOFT3D_context
*SC
)
2861 /* Convert BGR -> buffer */
2862 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2863 register ULONG size
=SC
->FragSize2
;
2867 Frag
[0].BufferRGBA
[0]=Frag
[0].Image8
[2];
2868 Frag
[0].BufferRGBA
[1]=Frag
[0].Image8
[1];
2869 Frag
[0].BufferRGBA
[2]=Frag
[0].Image8
[0];
2870 Frag
[0].BufferRGBA
[3]=ONE
;
2872 Frag
[1].BufferRGBA
[0]=Frag
[1].Image8
[2];
2873 Frag
[1].BufferRGBA
[1]=Frag
[1].Image8
[1];
2874 Frag
[1].BufferRGBA
[2]=Frag
[1].Image8
[0];
2875 Frag
[1].BufferRGBA
[3]=ONE
;
2880 /*=============================================================*/
2881 void PixelsOutBGR(struct SOFT3D_context
*SC
)
2883 /* Convert buffer -> BGR */
2884 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
2885 register ULONG size
=SC
->FragSize2
;
2889 Frag
[0].Image8
[0]=Frag
[0].BufferRGBA
[2];
2890 Frag
[0].Image8
[1]=Frag
[0].BufferRGBA
[1];
2891 Frag
[0].Image8
[2]=Frag
[0].BufferRGBA
[0];
2893 Frag
[1].Image8
[0]=Frag
[1].BufferRGBA
[2];
2894 Frag
[1].Image8
[1]=Frag
[1].BufferRGBA
[1];
2895 Frag
[1].Image8
[2]=Frag
[1].BufferRGBA
[0];
2900 /*=============================================================*/
2901 void SelectMipMap(struct SOFT3D_context
*SC
)
2903 struct SOFT3D_texture
*ST
=SC
->state
.ST
;
2907 if(ST
==NULL
) return;
2910 if(!Wazp3D
->DoMipMaps
.ON
) return;
2913 dmin
=SC
->dmin
>>(16-3); /* rescale dmin to [0 to 2048] */
2915 mm
=0; /* default: use biggest mipmap = more precision*/
2916 if(dmin
>=2048) mm
=11; /* Example we skip 3000 texels for each pixel ==> use a 1x1 texels mipmap[11] not the 2048x2048 original */
2917 if(dmin
>=1024) mm
=10;
2927 if(dmin
>=1) mm
=0; /* we skip 1 texel for each pixel ==> need the more precise(biggest) mipmap */
2931 SC
->MM
=&ST
->MMs
[mm
];
2933 /*=============================================================*/
2934 void Fill_BigTexPersp2_Gouraud_Fog(struct SOFT3D_context
*SC
)
2936 register UBYTE
*Image8
;
2937 register UBYTE
*Ztest
;
2938 register union pixel3D
*Pix
=SC
->Pix
;
2939 register struct SOFT3D_mipmap
*MM
=SC
->MM
;
2940 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
2941 register WORD high
=SC
->PolyHigh
;
2942 register WORD large
;
2944 SREM(Fill_BigTexPersp2_Gouraud_Fog
)
2948 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
2949 large
= Pix
->W
.large
;
2951 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
2956 Frag
->Image8
=Image8
;
2957 Frag
->Tex8
=MM
->Tex8U
[Pix
->W
.u
]+MM
->Tex8V
[Pix
->W
.v
];
2958 Frag
->Tex8
+=MM
->Tex8Ulow
[Pix
->W
.u3
]+MM
->Tex8Vlow
[Pix
->W
.v3
];
2959 Frag
->ColorRGBA
[0]=Pix
->W
.R
;
2960 Frag
->ColorRGBA
[1]=Pix
->W
.G
;
2961 Frag
->ColorRGBA
[2]=Pix
->W
.B
;
2962 Frag
->ColorRGBA
[3]=Pix
->W
.A
;
2963 COPYRGBA(Frag
->FogRGBA
,(&SC
->FogRGBAs
[Pix
->W
.F
]));
2966 Image8
=Image8
+Pix
->L
.bpp
;
2967 Pix
->L
.u
+=Pix
->L
.du
;
2968 Pix
->L
.v
+=Pix
->L
.dv
;
2969 Pix
->L
.du
+=Pix
->L
.ddu
;
2970 Pix
->L
.dv
+=Pix
->L
.ddv
;
2971 Pix
->L
.R
+=Pix
->L
.dR
;
2972 Pix
->L
.G
+=Pix
->L
.dG
;
2973 Pix
->L
.B
+=Pix
->L
.dB
;
2974 Pix
->L
.A
+=Pix
->L
.dA
;
2975 Pix
->L
.F
+=Pix
->L
.dF
;
2978 if(Frag
> SC
->FragBufferMaxi
)
2979 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
2982 SC
->FragBufferDone
=Frag
;
2984 /*=============================================================*/
2985 void Fill_BigTexPersp2(struct SOFT3D_context
*SC
)
2987 register UBYTE
*Image8
;
2988 register UBYTE
*Ztest
;
2989 register union pixel3D
*Pix
=SC
->Pix
;
2990 register struct SOFT3D_mipmap
*MM
=SC
->MM
;
2991 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
2992 register WORD high
=SC
->PolyHigh
;
2993 register WORD large
;
2995 SREM(Fill_BigTexPersp2
)
2999 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3000 large
= Pix
->W
.large
;
3002 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3007 Frag
->Image8
=Image8
;
3008 Frag
->Tex8
=MM
->Tex8U
[Pix
->W
.u
]+MM
->Tex8V
[Pix
->W
.v
];
3009 Frag
->Tex8
+=MM
->Tex8Ulow
[Pix
->W
.u3
]+MM
->Tex8Vlow
[Pix
->W
.v3
];
3010 COPYRGBA(Frag
->ColorRGBA
,SC
->FlatRGBA
);
3013 Image8
=Image8
+Pix
->L
.bpp
;
3014 Pix
->L
.u
+=Pix
->L
.du
;
3015 Pix
->L
.v
+=Pix
->L
.dv
;
3016 Pix
->L
.du
+=Pix
->L
.ddu
;
3017 Pix
->L
.dv
+=Pix
->L
.ddv
;
3021 if(Frag
> SC
->FragBufferMaxi
)
3022 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3025 SC
->FragBufferDone
=Frag
;
3027 /*=============================================================*/
3028 void Fill_TexPersp2_Gouraud_Fog(struct SOFT3D_context
*SC
)
3030 register UBYTE
*Image8
;
3031 register UBYTE
*Ztest
;
3032 register union pixel3D
*Pix
=SC
->Pix
;
3033 register struct SOFT3D_mipmap
*MM
=SC
->MM
;
3034 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3035 register WORD high
=SC
->PolyHigh
;
3036 register WORD large
;
3038 SREM(Fill_TexPersp2_Gouraud_Fog
)
3042 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3043 large
= Pix
->W
.large
;
3045 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3050 Frag
->Image8
=Image8
;
3051 Frag
->Tex8
=MM
->Tex8U
[Pix
->W
.u
]+MM
->Tex8V
[Pix
->W
.v
];
3052 Frag
->ColorRGBA
[0]=Pix
->W
.R
;
3053 Frag
->ColorRGBA
[1]=Pix
->W
.G
;
3054 Frag
->ColorRGBA
[2]=Pix
->W
.B
;
3055 Frag
->ColorRGBA
[3]=Pix
->W
.A
;
3056 COPYRGBA(Frag
->FogRGBA
,(&SC
->FogRGBAs
[Pix
->W
.F
]));
3059 Image8
=Image8
+Pix
->L
.bpp
;
3060 Pix
->L
.u
+=Pix
->L
.du
;
3061 Pix
->L
.v
+=Pix
->L
.dv
;
3062 Pix
->L
.du
+=Pix
->L
.ddu
;
3063 Pix
->L
.dv
+=Pix
->L
.ddv
;
3064 Pix
->L
.R
+=Pix
->L
.dR
;
3065 Pix
->L
.G
+=Pix
->L
.dG
;
3066 Pix
->L
.B
+=Pix
->L
.dB
;
3067 Pix
->L
.A
+=Pix
->L
.dA
;
3068 Pix
->L
.F
+=Pix
->L
.dF
;
3071 if(Frag
> SC
->FragBufferMaxi
)
3072 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3075 SC
->FragBufferDone
=Frag
;
3077 /*=============================================================*/
3078 void Fill_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
)
3080 register UBYTE
*Image8
;
3081 register UBYTE
*Ztest
;
3082 register union pixel3D
*Pix
=SC
->Pix
;
3083 register struct SOFT3D_mipmap
*MM
=SC
->MM
;
3084 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3085 register WORD high
=SC
->PolyHigh
;
3086 register WORD large
;
3088 if(SC
->state
.PerspMode
==2)
3089 {Fill_TexPersp2_Gouraud_Fog(SC
); return;}
3090 SREM(Fill_Tex_Gouraud_Fog
)
3094 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3095 large
= Pix
->W
.large
;
3097 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3102 Frag
->Image8
=Image8
;
3103 Frag
->Tex8
=MM
->Tex8U
[Pix
->W
.u
]+MM
->Tex8V
[Pix
->W
.v
];
3104 Frag
->ColorRGBA
[0]=Pix
->W
.R
;
3105 Frag
->ColorRGBA
[1]=Pix
->W
.G
;
3106 Frag
->ColorRGBA
[2]=Pix
->W
.B
;
3107 Frag
->ColorRGBA
[3]=Pix
->W
.A
;
3108 COPYRGBA(Frag
->FogRGBA
,(&SC
->FogRGBAs
[Pix
->W
.F
]));
3111 Image8
=Image8
+Pix
->L
.bpp
;
3112 Pix
->L
.u
+=Pix
->L
.du
;
3113 Pix
->L
.v
+=Pix
->L
.dv
;
3114 Pix
->L
.R
+=Pix
->L
.dR
;
3115 Pix
->L
.G
+=Pix
->L
.dG
;
3116 Pix
->L
.B
+=Pix
->L
.dB
;
3117 Pix
->L
.A
+=Pix
->L
.dA
;
3118 Pix
->L
.F
+=Pix
->L
.dF
;
3121 if(Frag
> SC
->FragBufferMaxi
)
3122 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3125 SC
->FragBufferDone
=Frag
;
3127 /*=============================================================*/
3128 void Fill_Gouraud_Fog(struct SOFT3D_context
*SC
)
3130 register UBYTE
*Image8
;
3131 register UBYTE
*Ztest
;
3132 register union pixel3D
*Pix
=SC
->Pix
;
3133 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3134 register WORD high
=SC
->PolyHigh
;
3135 register WORD large
;
3137 SREM(Fill_Gouraud_Fog
)
3141 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3142 large
= Pix
->W
.large
;
3144 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3149 Frag
->Image8
=Image8
;
3150 Frag
->ColorRGBA
[0]=Pix
->W
.R
;
3151 Frag
->ColorRGBA
[1]=Pix
->W
.G
;
3152 Frag
->ColorRGBA
[2]=Pix
->W
.B
;
3153 Frag
->ColorRGBA
[3]=Pix
->W
.A
;
3154 COPYRGBA(Frag
->FogRGBA
,(&SC
->FogRGBAs
[Pix
->W
.F
]));
3157 Image8
=Image8
+Pix
->L
.bpp
;
3158 Pix
->L
.R
+=Pix
->L
.dR
;
3159 Pix
->L
.G
+=Pix
->L
.dG
;
3160 Pix
->L
.B
+=Pix
->L
.dB
;
3161 Pix
->L
.A
+=Pix
->L
.dA
;
3162 Pix
->L
.F
+=Pix
->L
.dF
;
3165 if(Frag
> SC
->FragBufferMaxi
)
3166 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3169 SC
->FragBufferDone
=Frag
;
3171 /*=============================================================*/
3172 void Fill_Gouraud(struct SOFT3D_context
*SC
)
3174 register UBYTE
*Image8
;
3175 register UBYTE
*Ztest
;
3176 register union pixel3D
*Pix
=SC
->Pix
;
3177 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3178 register WORD high
=SC
->PolyHigh
;
3179 register WORD large
;
3185 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3186 large
= Pix
->W
.large
;
3188 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3193 Frag
->Image8
=Image8
;
3194 Frag
->ColorRGBA
[0]=Pix
->W
.R
;
3195 Frag
->ColorRGBA
[1]=Pix
->W
.G
;
3196 Frag
->ColorRGBA
[2]=Pix
->W
.B
;
3197 Frag
->ColorRGBA
[3]=Pix
->W
.A
;
3200 Image8
=Image8
+Pix
->L
.bpp
;
3201 Pix
->L
.R
+=Pix
->L
.dR
;
3202 Pix
->L
.G
+=Pix
->L
.dG
;
3203 Pix
->L
.B
+=Pix
->L
.dB
;
3204 Pix
->L
.A
+=Pix
->L
.dA
;
3207 if(Frag
> SC
->FragBufferMaxi
)
3208 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3211 SC
->FragBufferDone
=Frag
;
3213 /*=============================================================*/
3214 void Fill_Fog(struct SOFT3D_context
*SC
)
3216 register UBYTE
*Image8
;
3217 register UBYTE
*Ztest
;
3218 register union pixel3D
*Pix
=SC
->Pix
;
3219 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3220 register WORD high
=SC
->PolyHigh
;
3221 register WORD large
;
3227 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3228 large
= Pix
->W
.large
;
3230 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3235 Frag
->Image8
=Image8
;
3236 COPYRGBA(Frag
->ColorRGBA
,SC
->FlatRGBA
);
3237 COPYRGBA(Frag
->FogRGBA
,(&SC
->FogRGBAs
[Pix
->W
.F
]));
3240 Image8
=Image8
+Pix
->L
.bpp
;
3241 Pix
->L
.F
+=Pix
->L
.dF
;
3244 if(Frag
> SC
->FragBufferMaxi
)
3245 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3248 SC
->FragBufferDone
=Frag
;
3250 /*=============================================================*/
3251 void Fill_TexPersp2_Gouraud(struct SOFT3D_context
*SC
)
3253 register UBYTE
*Image8
;
3254 register UBYTE
*Ztest
;
3255 register union pixel3D
*Pix
=SC
->Pix
;
3256 register struct SOFT3D_mipmap
*MM
=SC
->MM
;
3257 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3258 register WORD high
=SC
->PolyHigh
;
3259 register WORD large
;
3261 SREM(Fill_TexPersp2_Gouraud
)
3265 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3266 large
= Pix
->W
.large
;
3268 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3273 Frag
->Image8
=Image8
;
3274 Frag
->Tex8
=MM
->Tex8U
[Pix
->W
.u
]+MM
->Tex8V
[Pix
->W
.v
];
3275 Frag
->ColorRGBA
[0]=Pix
->W
.R
;
3276 Frag
->ColorRGBA
[1]=Pix
->W
.G
;
3277 Frag
->ColorRGBA
[2]=Pix
->W
.B
;
3278 Frag
->ColorRGBA
[3]=Pix
->W
.A
;
3281 Image8
=Image8
+Pix
->L
.bpp
;
3282 Pix
->L
.u
+=Pix
->L
.du
;
3283 Pix
->L
.v
+=Pix
->L
.dv
;
3284 Pix
->L
.du
+=Pix
->L
.ddu
;
3285 Pix
->L
.dv
+=Pix
->L
.ddv
;
3286 Pix
->L
.R
+=Pix
->L
.dR
;
3287 Pix
->L
.G
+=Pix
->L
.dG
;
3288 Pix
->L
.B
+=Pix
->L
.dB
;
3289 Pix
->L
.A
+=Pix
->L
.dA
;
3292 if(Frag
> SC
->FragBufferMaxi
)
3293 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3296 SC
->FragBufferDone
=Frag
;
3298 /*=============================================================*/
3299 void Fill_Tex_Gouraud(struct SOFT3D_context
*SC
)
3301 register UBYTE
*Image8
;
3302 register UBYTE
*Ztest
;
3303 register union pixel3D
*Pix
=SC
->Pix
;
3304 register struct SOFT3D_mipmap
*MM
=SC
->MM
;
3305 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3306 register WORD high
=SC
->PolyHigh
;
3307 register WORD large
;
3309 if(SC
->state
.PerspMode
==2)
3310 {Fill_TexPersp2_Gouraud(SC
); return;}
3311 SREM(Fill_Tex_Gouraud
)
3315 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3316 large
= Pix
->W
.large
;
3318 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3323 Frag
->Image8
=Image8
;
3324 Frag
->Tex8
=MM
->Tex8U
[Pix
->W
.u
]+MM
->Tex8V
[Pix
->W
.v
];
3325 Frag
->ColorRGBA
[0]=Pix
->W
.R
;
3326 Frag
->ColorRGBA
[1]=Pix
->W
.G
;
3327 Frag
->ColorRGBA
[2]=Pix
->W
.B
;
3328 Frag
->ColorRGBA
[3]=Pix
->W
.A
;
3331 Image8
=Image8
+Pix
->L
.bpp
;
3332 Pix
->L
.u
+=Pix
->L
.du
;
3333 Pix
->L
.v
+=Pix
->L
.dv
;
3334 Pix
->L
.R
+=Pix
->L
.dR
;
3335 Pix
->L
.G
+=Pix
->L
.dG
;
3336 Pix
->L
.B
+=Pix
->L
.dB
;
3337 Pix
->L
.A
+=Pix
->L
.dA
;
3340 if(Frag
> SC
->FragBufferMaxi
)
3341 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3344 SC
->FragBufferDone
=Frag
;
3346 /*=============================================================*/
3347 void Fill_TexPersp2_Fog(struct SOFT3D_context
*SC
)
3349 register UBYTE
*Image8
;
3350 register UBYTE
*Ztest
;
3351 register union pixel3D
*Pix
=SC
->Pix
;
3352 register struct SOFT3D_mipmap
*MM
=SC
->MM
;
3353 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3354 register WORD high
=SC
->PolyHigh
;
3355 register WORD large
;
3358 SREM(Fill_TexPersp2_Fog
)
3362 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3363 large
= Pix
->W
.large
;
3365 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3370 Frag
->Image8
=Image8
;
3371 Frag
->Tex8
=MM
->Tex8U
[Pix
->W
.u
]+MM
->Tex8V
[Pix
->W
.v
];
3372 COPYRGBA(Frag
->ColorRGBA
,SC
->FlatRGBA
);
3373 COPYRGBA(Frag
->FogRGBA
,(&SC
->FogRGBAs
[Pix
->W
.F
]));
3376 Image8
=Image8
+Pix
->L
.bpp
;
3377 Pix
->L
.u
+=Pix
->L
.du
;
3378 Pix
->L
.v
+=Pix
->L
.dv
;
3379 Pix
->L
.du
+=Pix
->L
.ddu
;
3380 Pix
->L
.dv
+=Pix
->L
.ddv
;
3381 Pix
->L
.F
+=Pix
->L
.dF
;
3384 if(Frag
> SC
->FragBufferMaxi
)
3385 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3388 SC
->FragBufferDone
=Frag
;
3390 /*=============================================================*/
3391 void Fill_Tex_Fog(struct SOFT3D_context
*SC
)
3393 register UBYTE
*Image8
;
3394 register UBYTE
*Ztest
;
3395 register union pixel3D
*Pix
=SC
->Pix
;
3396 register struct SOFT3D_mipmap
*MM
=SC
->MM
;
3397 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3398 register WORD high
=SC
->PolyHigh
;
3399 register WORD large
;
3401 if(SC
->state
.PerspMode
==2)
3402 {Fill_TexPersp2_Fog(SC
); return;}
3407 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3408 large
= Pix
->W
.large
;
3410 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3415 Frag
->Image8
=Image8
;
3416 Frag
->Tex8
=MM
->Tex8U
[Pix
->W
.u
]+MM
->Tex8V
[Pix
->W
.v
];
3417 COPYRGBA(Frag
->ColorRGBA
,SC
->FlatRGBA
);
3418 COPYRGBA(Frag
->FogRGBA
,(&SC
->FogRGBAs
[Pix
->W
.F
]));
3421 Image8
=Image8
+Pix
->L
.bpp
;
3422 Pix
->L
.u
+=Pix
->L
.du
;
3423 Pix
->L
.v
+=Pix
->L
.dv
;
3424 Pix
->L
.F
+=Pix
->L
.dF
;
3427 if(Frag
> SC
->FragBufferMaxi
)
3428 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3431 SC
->FragBufferDone
=Frag
;
3433 /*=============================================================*/
3434 void Fill_TexPersp2(struct SOFT3D_context
*SC
)
3436 register UBYTE
*Image8
;
3437 register UBYTE
*Ztest
;
3438 register union pixel3D
*Pix
=SC
->Pix
;
3439 register struct SOFT3D_mipmap
*MM
=SC
->MM
;
3440 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3441 register WORD high
=SC
->PolyHigh
;
3442 register WORD large
;
3444 SREM(Fill_TexPersp2
)
3447 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3448 large
= Pix
->W
.large
;
3450 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3455 Frag
->Image8
=Image8
;
3456 Frag
->Tex8
=MM
->Tex8U
[Pix
->W
.u
]+MM
->Tex8V
[Pix
->W
.v
];
3457 COPYRGBA(Frag
->ColorRGBA
,SC
->FlatRGBA
);
3460 Image8
=Image8
+Pix
->L
.bpp
;
3461 Pix
->L
.u
+=Pix
->L
.du
;
3462 Pix
->L
.v
+=Pix
->L
.dv
;
3463 Pix
->L
.du
+=Pix
->L
.ddu
;
3464 Pix
->L
.dv
+=Pix
->L
.ddv
;
3467 if(Frag
> SC
->FragBufferMaxi
)
3468 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3471 SC
->FragBufferDone
=Frag
;
3473 /*=============================================================*/
3474 void Fill_TexMul(struct SOFT3D_context
*SC
)
3476 register UBYTE
*Image8
;
3477 register UBYTE
*Ztest
;
3478 register union pixel3D
*Pix
=SC
->Pix
;
3479 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3480 register WORD high
=SC
->PolyHigh
;
3481 register WORD large
;
3482 struct SOFT3D_texture
*ST
=SC
->state
.ST
;
3483 register UBYTE
*tex8
=ST
->pt
;
3484 register UWORD texU
=ST
->bits
/8;
3485 register UWORD texV
=ST
->large
*ST
->bits
/8;
3491 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3492 large
= Pix
->W
.large
;
3494 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3499 Frag
->Image8
=Image8
;
3501 Frag
->Tex8
+=Pix
->W
.u
* texU
;
3502 Frag
->Tex8
+=Pix
->W
.v
* texV
;
3503 COPYRGBA(Frag
->ColorRGBA
,SC
->FlatRGBA
);
3506 Image8
=Image8
+Pix
->L
.bpp
;
3507 Pix
->L
.u
+=Pix
->L
.du
;
3508 Pix
->L
.v
+=Pix
->L
.dv
;
3511 if(Frag
> SC
->FragBufferMaxi
)
3512 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3515 SC
->FragBufferDone
=Frag
;
3517 /*=============================================================*/
3518 void Fill_Tex(struct SOFT3D_context
*SC
)
3520 register UBYTE
*Image8
;
3521 register UBYTE
*Ztest
;
3522 register union pixel3D
*Pix
=SC
->Pix
;
3523 register struct SOFT3D_mipmap
*MM
=SC
->MM
;
3524 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3525 register WORD high
=SC
->PolyHigh
;
3526 register WORD large
;
3528 if(SC
->state
.PerspMode
==2)
3529 {Fill_TexPersp2(SC
); return;}
3531 if(Wazp3D
->DebugDriver
.ON
) /* Just a way to test that function speed */
3532 {Fill_TexMul(SC
); return;}
3537 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3538 large
= Pix
->W
.large
;
3540 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3545 Frag
->Image8
=Image8
;
3546 Frag
->Tex8
=MM
->Tex8U
[Pix
->W
.u
]+MM
->Tex8V
[Pix
->W
.v
];
3547 COPYRGBA(Frag
->ColorRGBA
,SC
->FlatRGBA
);
3550 Image8
=Image8
+Pix
->L
.bpp
;
3551 Pix
->L
.u
+=Pix
->L
.du
;
3552 Pix
->L
.v
+=Pix
->L
.dv
;
3555 if(Frag
> SC
->FragBufferMaxi
)
3556 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3559 SC
->FragBufferDone
=Frag
;
3561 /*=============================================================*/
3562 void Fill_Flat(struct SOFT3D_context
*SC
)
3564 register UBYTE
*Image8
;
3565 register UBYTE
*Ztest
;
3566 register union pixel3D
*Pix
=SC
->Pix
;
3567 register struct fragbuffer3D
*Frag
=SC
->FragBufferDone
;
3568 register WORD high
=SC
->PolyHigh
;
3569 register WORD large
;
3575 Image8
= Pix
->L
.Image8Y
+ SC
->Image8X
[Pix
->W
.x
];
3576 large
= Pix
->W
.large
;
3578 SC
->Pix
=Pix
; SC
->FunctionZtest(SC
); Ztest
=SC
->Ztest
;
3583 Frag
->Image8
=Image8
;
3584 COPYRGBA(Frag
->ColorRGBA
,SC
->FlatRGBA
);
3587 Image8
=Image8
+Pix
->L
.bpp
;
3590 if(Frag
> SC
->FragBufferMaxi
)
3591 {SC
->FragBufferDone
=Frag
; SOFT3D_Flush(SC
); Frag
=SC
->FragBuffer
;}
3594 SC
->FragBufferDone
=Frag
;
3596 /*=============================================================*/
3597 void Ztest_znever_update(struct SOFT3D_context
*SC
)
3599 register UBYTE
*Ztest
=SC
->Ztest
;
3600 register union pixel3D
*Pix
=SC
->Pix
;
3601 register WORD large
=Pix
->W
.large
;
3604 { *Ztest
=(FALSE
); Ztest
++; }
3606 /*=============================================================*/
3607 void Ztest_zless_update(struct SOFT3D_context
*SC
)
3609 register UBYTE
*Ztest
=SC
->Ztest
;
3610 register union pixel3D
*Pix
=SC
->Pix
;
3611 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3612 register ZBUFF dz
=Pix
->L
.dz
;
3613 register WORD large
=Pix
->W
.large
;
3616 { *Ztest
=(ZVALUE
< *Zbuffer
); if(*Ztest
) *Zbuffer
=ZVALUE
; Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
;}
3618 /*=============================================================*/
3619 void Ztest_zgequal_update(struct SOFT3D_context
*SC
)
3621 register UBYTE
*Ztest
=SC
->Ztest
;
3622 register union pixel3D
*Pix
=SC
->Pix
;
3623 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3624 register ZBUFF dz
=Pix
->L
.dz
;
3625 register WORD large
=Pix
->W
.large
;
3628 { *Ztest
=(ZVALUE
>= *Zbuffer
); if(*Ztest
) *Zbuffer
=ZVALUE
; Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
;}
3630 /*=============================================================*/
3631 void Ztest_zlequal_update(struct SOFT3D_context
*SC
)
3633 register UBYTE
*Ztest
=SC
->Ztest
;
3634 register union pixel3D
*Pix
=SC
->Pix
;
3635 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3636 register ZBUFF dz
=Pix
->L
.dz
;
3637 register WORD large
=Pix
->W
.large
;
3640 { *Ztest
=(ZVALUE
<= *Zbuffer
); if(*Ztest
) *Zbuffer
=ZVALUE
; Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
;}
3642 /*=============================================================*/
3643 void Ztest_zgreater_update(struct SOFT3D_context
*SC
)
3645 register UBYTE
*Ztest
=SC
->Ztest
;
3646 register union pixel3D
*Pix
=SC
->Pix
;
3647 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3648 register ZBUFF dz
=Pix
->L
.dz
;
3649 register WORD large
=Pix
->W
.large
;
3652 { *Ztest
=(ZVALUE
> *Zbuffer
); if(*Ztest
) *Zbuffer
=ZVALUE
; Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
;}
3654 /*=============================================================*/
3655 void Ztest_znotequal_update(struct SOFT3D_context
*SC
)
3657 register UBYTE
*Ztest
=SC
->Ztest
;
3658 register union pixel3D
*Pix
=SC
->Pix
;
3659 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3660 register ZBUFF dz
=Pix
->L
.dz
;
3661 register WORD large
=Pix
->W
.large
;
3664 { *Ztest
=(ZVALUE
!= *Zbuffer
); if(*Ztest
) *Zbuffer
=ZVALUE
; Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
;}
3666 /*=============================================================*/
3667 void Ztest_zequal_update(struct SOFT3D_context
*SC
)
3669 register UBYTE
*Ztest
=SC
->Ztest
;
3670 register union pixel3D
*Pix
=SC
->Pix
;
3671 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3672 register ZBUFF dz
=Pix
->L
.dz
;
3673 register WORD large
=Pix
->W
.large
;
3676 { *Ztest
=(ZVALUE
== *Zbuffer
); if(*Ztest
) *Zbuffer
=ZVALUE
; Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
;}
3678 /*=============================================================*/
3679 void Ztest_zalways_update(struct SOFT3D_context
*SC
)
3681 register UBYTE
*Ztest
=SC
->Ztest
;
3682 register union pixel3D
*Pix
=SC
->Pix
;
3683 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3684 register ZBUFF dz
=Pix
->L
.dz
;
3685 register WORD large
=Pix
->W
.large
;
3688 { *Ztest
=(TRUE
); *Zbuffer
=ZVALUE
; Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
;}
3690 /*=============================================================*/
3691 /* void Ztest_znever(struct SOFT3D_context *SC) same as Ztest_znever_update */
3692 /*=============================================================*/
3693 void Ztest_zless(struct SOFT3D_context
*SC
)
3695 register UBYTE
*Ztest
=SC
->Ztest
;
3696 register union pixel3D
*Pix
=SC
->Pix
;
3697 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3698 register ZBUFF dz
=Pix
->L
.dz
;
3699 register WORD large
=Pix
->W
.large
;
3702 { *Ztest
=(ZVALUE
< *Zbuffer
); Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
; }
3704 /*=============================================================*/
3705 void Ztest_zgequal(struct SOFT3D_context
*SC
)
3707 register UBYTE
*Ztest
=SC
->Ztest
;
3708 register union pixel3D
*Pix
=SC
->Pix
;
3709 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3710 register ZBUFF dz
=Pix
->L
.dz
;
3711 register WORD large
=Pix
->W
.large
;
3714 { *Ztest
=(ZVALUE
>= *Zbuffer
); Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
; }
3716 /*=============================================================*/
3717 void Ztest_zlequal(struct SOFT3D_context
*SC
)
3719 register UBYTE
*Ztest
=SC
->Ztest
;
3720 register union pixel3D
*Pix
=SC
->Pix
;
3721 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3722 register ZBUFF dz
=Pix
->L
.dz
;
3723 register WORD large
=Pix
->W
.large
;
3726 { *Ztest
=(ZVALUE
<= *Zbuffer
); Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
; }
3728 /*=============================================================*/
3729 void Ztest_zgreater(struct SOFT3D_context
*SC
)
3731 register UBYTE
*Ztest
=SC
->Ztest
;
3732 register union pixel3D
*Pix
=SC
->Pix
;
3733 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3734 register ZBUFF dz
=Pix
->L
.dz
;
3735 register WORD large
=Pix
->W
.large
;
3738 { *Ztest
=(ZVALUE
> *Zbuffer
); Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
; }
3740 /*=============================================================*/
3741 void Ztest_znotequal(struct SOFT3D_context
*SC
)
3743 register UBYTE
*Ztest
=SC
->Ztest
;
3744 register union pixel3D
*Pix
=SC
->Pix
;
3745 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3746 register ZBUFF dz
=Pix
->L
.dz
;
3747 register WORD large
=Pix
->W
.large
;
3750 { *Ztest
=(ZVALUE
!= *Zbuffer
); Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
; }
3752 /*=============================================================*/
3753 void Ztest_zequal(struct SOFT3D_context
*SC
)
3755 register UBYTE
*Ztest
=SC
->Ztest
;
3756 register union pixel3D
*Pix
=SC
->Pix
;
3757 register ZBUFF
*Zbuffer
= &(Pix
->L
.ZbufferY
[Pix
->W
.x
]);
3758 register ZBUFF dz
=Pix
->L
.dz
;
3759 register WORD large
=Pix
->W
.large
;
3762 { *Ztest
=(ZVALUE
== *Zbuffer
); Ztest
++; Zbuffer
++; Pix
->L
.z
+=dz
; }
3764 /*=============================================================*/
3765 void Ztest_zalways(struct SOFT3D_context
*SC
)
3767 register UBYTE
*Ztest
=SC
->Ztest
;
3768 register union pixel3D
*Pix
=SC
->Pix
;
3769 register WORD large
=Pix
->W
.large
;
3772 { *Ztest
=(TRUE
); Ztest
++; }
3774 /*=============================================================*/
3775 void EdgeMinDeltas(struct SOFT3D_context
*SC
,union pixel3D
*P1
,union pixel3D
*P2
)
3777 /* for selecting mipmap find the minimum uv linear delta */
3779 register LONG u
,v
,du
,dv
;
3781 if(SC
->state
.ST
==NULL
) /* = Color only so dont bother with mipmapped-texturing*/
3788 size
=P2
->W
.y
- P1
->W
.y
;
3791 size
=P2
->W
.x
- P1
->W
.x
;
3796 u
=(P2
->L
.u
- P1
->L
.u
);
3797 v
=(P2
->L
.v
- P1
->L
.v
);
3804 if(du
<0) du
=-du
; /* absolute value */
3808 if(du
<SC
->dmin
) /* find minimal delta = texture step */
3812 if(dv
<SC
->dmin
) /* find minimal delta = texture step */
3819 /*=============================================================*/
3820 void Edge_Persp_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
)
3822 register union pixel3D
*P1
=SC
->P1
;
3823 register union pixel3D
*P2
=SC
->P2
;
3824 register WORD high
,n
;
3825 double u
,v
,u2
,v2
,du
,dv
,w
;
3826 union pixel3D DeltaY
;
3828 SFUNCTION(Edge_Persp_Tex_Gouraud_Fog
)
3829 high
=P2
->W
.y
- P1
->W
.y
;
3832 DeltaY
.L
.dx
=(P2
->L
.x
- P1
->L
.x
)/high
;
3833 DeltaY
.L
.dz
=(P2
->L
.z
- P1
->L
.z
)/high
;
3834 DeltaY
.L
.dw
=(P2
->L
.w
- P1
->L
.w
)/high
;
3835 DeltaY
.L
.dR
=(P2
->L
.R
- P1
->L
.R
)/high
;
3836 DeltaY
.L
.dG
=(P2
->L
.G
- P1
->L
.G
)/high
;
3837 DeltaY
.L
.dB
=(P2
->L
.B
- P1
->L
.B
)/high
;
3838 DeltaY
.L
.dA
=(P2
->L
.A
- P1
->L
.A
)/high
;
3839 DeltaY
.L
.dF
=(P2
->L
.F
- P1
->L
.F
)/high
;
3841 u
=(double)P1
->L
.u
* P1
->L
.w
;
3842 u2
=(double)P2
->L
.u
* P2
->L
.w
;
3843 v
=(double)P1
->L
.v
* P1
->L
.w
;
3844 v2
=(double)P2
->L
.v
* P2
->L
.w
;
3849 high
--; /* ne pas recalculer les points extremites */
3852 P1
[1].L
.x
=P1
->L
.x
+DeltaY
.L
.dx
;
3853 P1
[1].L
.z
=P1
->L
.z
+DeltaY
.L
.dz
;
3854 P1
[1].L
.w
=P1
->L
.w
+DeltaY
.L
.dw
;
3855 P1
[1].L
.R
=P1
->L
.R
+DeltaY
.L
.dR
;
3856 P1
[1].L
.G
=P1
->L
.G
+DeltaY
.L
.dG
;
3857 P1
[1].L
.B
=P1
->L
.B
+DeltaY
.L
.dB
;
3858 P1
[1].L
.A
=P1
->L
.A
+DeltaY
.L
.dA
;
3859 P1
[1].L
.F
=P1
->L
.F
+DeltaY
.L
.dF
;
3868 /*=============================================================*/
3869 void Edge_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
)
3871 register union pixel3D
*P1
=SC
->P1
;
3872 register union pixel3D
*P2
=SC
->P2
;
3873 register WORD high
,n
;
3874 union pixel3D DeltaY
;
3876 if(Wazp3D
->DoMipMaps
.ON
)
3877 EdgeMinDeltas(SC
,P1
,P2
);
3879 high
=P2
->W
.y
- P1
->W
.y
;
3882 SFUNCTION(Edge_Tex_Gouraud_Fog
)
3883 DeltaY
.L
.dx
=(P2
->L
.x
- P1
->L
.x
)/high
;
3884 DeltaY
.L
.dz
=(P2
->L
.z
- P1
->L
.z
)/high
;
3885 DeltaY
.L
.du
=(P2
->L
.u
- P1
->L
.u
)/high
;
3886 DeltaY
.L
.dv
=(P2
->L
.v
- P1
->L
.v
)/high
;
3887 DeltaY
.L
.dR
=(P2
->L
.R
- P1
->L
.R
)/high
;
3888 DeltaY
.L
.dG
=(P2
->L
.G
- P1
->L
.G
)/high
;
3889 DeltaY
.L
.dB
=(P2
->L
.B
- P1
->L
.B
)/high
;
3890 DeltaY
.L
.dA
=(P2
->L
.A
- P1
->L
.A
)/high
;
3891 DeltaY
.L
.dF
=(P2
->L
.F
- P1
->L
.F
)/high
;
3893 high
--; /* ne pas recalculer les points extremites */
3896 P1
[1].L
.x
=P1
->L
.x
+DeltaY
.L
.dx
;
3897 P1
[1].L
.z
=P1
->L
.z
+DeltaY
.L
.dz
;
3898 P1
[1].L
.u
=P1
->L
.u
+DeltaY
.L
.du
;
3899 P1
[1].L
.v
=P1
->L
.v
+DeltaY
.L
.dv
;
3900 P1
[1].L
.R
=P1
->L
.R
+DeltaY
.L
.dR
;
3901 P1
[1].L
.G
=P1
->L
.G
+DeltaY
.L
.dG
;
3902 P1
[1].L
.B
=P1
->L
.B
+DeltaY
.L
.dB
;
3903 P1
[1].L
.A
=P1
->L
.A
+DeltaY
.L
.dA
;
3904 P1
[1].L
.F
=P1
->L
.F
+DeltaY
.L
.dF
;
3908 /*=============================================================*/
3909 void Edge_Gouraud(struct SOFT3D_context
*SC
)
3911 register union pixel3D
*P1
=SC
->P1
;
3912 register union pixel3D
*P2
=SC
->P2
;
3913 register WORD high
,n
;
3914 union pixel3D DeltaY
;
3916 high
=P2
->W
.y
- P1
->W
.y
;
3919 SFUNCTION(Edge_Gouraud
)
3920 DeltaY
.L
.dx
=(P2
->L
.x
- P1
->L
.x
)/high
;
3921 DeltaY
.L
.dz
=(P2
->L
.z
- P1
->L
.z
)/high
;
3922 DeltaY
.L
.dR
=(P2
->L
.R
- P1
->L
.R
)/high
;
3923 DeltaY
.L
.dG
=(P2
->L
.G
- P1
->L
.G
)/high
;
3924 DeltaY
.L
.dB
=(P2
->L
.B
- P1
->L
.B
)/high
;
3925 DeltaY
.L
.dA
=(P2
->L
.A
- P1
->L
.A
)/high
;
3927 high
--; /* ne pas recalculer les points extremites */
3930 P1
[1].L
.x
=P1
->L
.x
+DeltaY
.L
.dx
;
3931 P1
[1].L
.z
=P1
->L
.z
+DeltaY
.L
.dz
;
3932 P1
[1].L
.R
=P1
->L
.R
+DeltaY
.L
.dR
;
3933 P1
[1].L
.G
=P1
->L
.G
+DeltaY
.L
.dG
;
3934 P1
[1].L
.B
=P1
->L
.B
+DeltaY
.L
.dB
;
3935 P1
[1].L
.A
=P1
->L
.A
+DeltaY
.L
.dA
;
3939 /*=============================================================*/
3940 void Edge_Flat(struct SOFT3D_context
*SC
)
3942 register union pixel3D
*P1
=SC
->P1
;
3943 register union pixel3D
*P2
=SC
->P2
;
3944 register WORD high
,n
;
3945 union pixel3D DeltaY
;
3947 high
=P2
->W
.y
- P1
->W
.y
;
3950 SFUNCTION(Edge_Flat
)
3951 DeltaY
.L
.dx
=(P2
->L
.x
- P1
->L
.x
)/high
;
3952 DeltaY
.L
.dz
=(P2
->L
.z
- P1
->L
.z
)/high
;
3954 high
--; /* ne pas recalculer les points extremites */
3957 P1
[1].L
.x
=P1
->L
.x
+DeltaY
.L
.dx
;
3958 P1
[1].L
.z
=P1
->L
.z
+DeltaY
.L
.dz
;
3962 /*=============================================================*/
3963 void Edge_Persp_Tex(struct SOFT3D_context
*SC
)
3965 register union pixel3D
*P1
=SC
->P1
;
3966 register union pixel3D
*P2
=SC
->P2
;
3967 register WORD high
,n
;
3968 double u
,v
,u2
,v2
,du
,dv
,w
;
3969 union pixel3D DeltaY
;
3971 SFUNCTION(Edge_Persp_Tex
)
3972 high
=P2
->W
.y
- P1
->W
.y
;
3975 DeltaY
.L
.dx
=(P2
->L
.x
- P1
->L
.x
)/high
;
3976 DeltaY
.L
.dz
=(P2
->L
.z
- P1
->L
.z
)/high
;
3977 DeltaY
.L
.dw
=(P2
->L
.w
- P1
->L
.w
)/high
;
3979 u
=(double)P1
->L
.u
* P1
->L
.w
;
3980 u2
=(double)P2
->L
.u
* P2
->L
.w
;
3981 v
=(double)P1
->L
.v
* P1
->L
.w
;
3982 v2
=(double)P2
->L
.v
* P2
->L
.w
;
3987 high
--; /* ne pas recalculer les points extremites */
3990 P1
[1].L
.x
=P1
->L
.x
+DeltaY
.L
.dx
;
3991 P1
[1].L
.z
=P1
->L
.z
+DeltaY
.L
.dz
;
3992 P1
[1].L
.w
=P1
->L
.w
+DeltaY
.L
.dw
;
4001 /*=============================================================*/
4002 void Edge_Tex(struct SOFT3D_context
*SC
)
4004 register union pixel3D
*P1
=SC
->P1
;
4005 register union pixel3D
*P2
=SC
->P2
;
4006 register WORD high
,n
;
4007 union pixel3D DeltaY
;
4009 if(Wazp3D
->DoMipMaps
.ON
)
4010 EdgeMinDeltas(SC
,P1
,P2
);
4012 high
=P2
->W
.y
- P1
->W
.y
;
4016 DeltaY
.L
.dx
=(P2
->L
.x
- P1
->L
.x
)/high
;
4017 DeltaY
.L
.dz
=(P2
->L
.z
- P1
->L
.z
)/high
;
4018 DeltaY
.L
.du
=(P2
->L
.u
- P1
->L
.u
)/high
;
4019 DeltaY
.L
.dv
=(P2
->L
.v
- P1
->L
.v
)/high
;
4021 high
--; /* ne pas recalculer les points extremites */
4024 P1
[1].L
.x
=P1
->L
.x
+DeltaY
.L
.dx
;
4025 P1
[1].L
.z
=P1
->L
.z
+DeltaY
.L
.dz
;
4026 P1
[1].L
.u
=P1
->L
.u
+DeltaY
.L
.du
;
4027 P1
[1].L
.v
=P1
->L
.v
+DeltaY
.L
.dv
;
4032 /*=============================================================*/
4033 void SOFT3D_SetDrawState(APTR sc
,APTR sta
)
4035 struct state3D
*state
=sta
;
4036 struct SOFT3D_context
*SC
=sc
;
4037 struct SOFT3D_texture
*ST
=state
->ST
;
4040 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
4041 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
4042 SFUNCTION(SOFT3D_SetDrawState
)
4043 if(Wazp3D
->DebugSOFT3D
.ON
)
4045 Libprintf(" state:Changed%ld UseTex%ld ST%ld ZMode%ld TexEnvMode%ld BlendMode%ld UseGouraud%ld UseFog%ld\n",(ULONG
)state
->Changed
,(ULONG
)state
->UseTex
,(IPTR
)state
->ST
,(ULONG
)state
->ZMode
,(ULONG
)state
->TexEnvMode
,(ULONG
)state
->BlendMode
,(ULONG
)state
->UseGouraud
,(ULONG
)state
->UseFog
);
4047 Libprintf(" CurrentRGBA: %ld %ld %ld %ld\n",(ULONG
)state
->CurrentRGBA
[0],(ULONG
)state
->CurrentRGBA
[1],(ULONG
)state
->CurrentRGBA
[2],(ULONG
)state
->CurrentRGBA
[3]);
4052 SREM( state unchanged
) /* not changed ==> do nothing */
4056 if(Wazp3D
->UseStateTracker
.ON
)
4057 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont change states */
4058 if(SC
->state
.ST
==state
->ST
)
4059 if(SC
->state
.ZMode
==state
->ZMode
)
4060 if(SC
->state
.BlendMode
==state
->BlendMode
)
4061 if(SC
->state
.TexEnvMode
==state
->TexEnvMode
)
4062 if(SC
->state
.PerspMode
==state
->PerspMode
)
4063 if(SC
->state
.CullingMode
==state
->CullingMode
)
4064 if(SC
->state
.FogMode
==state
->FogMode
)
4065 if(SC
->state
.UseGouraud
==state
->UseGouraud
)
4066 if(SC
->state
.UseTex
==state
->UseTex
)
4067 if(SC
->state
.UseFog
==state
->UseFog
)
4068 if(SAMERGBA(SC
->state
.FogRGBA
,state
->FogRGBA
))
4069 if(SAMERGBA(SC
->state
.CurrentRGBA
,state
->CurrentRGBA
))
4070 if(SAMERGBA(SC
->state
.EnvRGBA
,state
->EnvRGBA
))
4071 if(SC
->state
.PointSize
==state
->PointSize
)
4072 if(SC
->state
.LineSize
==state
->LineSize
)
4073 if(SC
->state
.FogZmin
==state
->FogZmin
)
4074 if(SC
->state
.FogZmax
==state
->FogZmax
)
4075 if(SC
->state
.FogDensity
==state
->FogDensity
)
4077 SREM( all same states
) /* if nothing truly changed ==> do nothing */
4078 SC
->state
.Changed
=state
->Changed
=FALSE
;
4083 SC
->state
.ZMode
=state
->ZMode
;
4084 SC
->state
.BlendMode
=state
->BlendMode
;
4085 SC
->state
.TexEnvMode
=state
->TexEnvMode
;
4086 SC
->state
.PerspMode
=state
->PerspMode
;
4087 SC
->state
.CullingMode
=state
->CullingMode
;
4088 SC
->state
.FogMode
=state
->FogMode
;
4089 SC
->state
.UseGouraud
=state
->UseGouraud
;
4090 SC
->state
.UseTex
=state
->UseTex
;
4091 SC
->state
.UseFog
=state
->UseFog
;
4092 COPYRGBA(SC
->state
.FogRGBA
,state
->FogRGBA
);
4093 COPYRGBA(SC
->state
.CurrentRGBA
,state
->CurrentRGBA
);
4094 COPYRGBA(SC
->state
.EnvRGBA
,state
->EnvRGBA
);
4095 COPYRGBA(SC
->state
.BackRGBA
,state
->BackRGBA
);
4096 SC
->state
.PointSize
=state
->PointSize
;
4097 SC
->state
.LineSize
=state
->LineSize
;
4098 SC
->state
.FogZmin
=state
->FogZmin
;
4099 SC
->state
.FogZmax
=state
->FogZmax
;
4100 SC
->state
.FogDensity
=state
->FogDensity
;
4101 SC
->state
.ST
=state
->ST
;
4105 SC
->state
.gltex
=ST
->HT
.gltex
; /*direct access to gltex value */
4106 SC
->HC
.state
=&SC
->state
; /*direct access to state */
4109 /* flush remaining pixels before any changes */
4112 /* Now change hardware/software drawing functions */
4114 if(SC
->UseHard
) HARD3D_SetDrawFunctions(&SC
->HC
);
4116 if(!SC
->UseHard
) SOFT3D_SetDrawFunctions(sc
);
4118 SC
->state
.Changed
=state
->Changed
=FALSE
; /* change treated */
4120 /*=============================================================*/
4121 void SOFT3D_SetDrawFunctions(APTR sc
)
4123 struct SOFT3D_context
*SC
=sc
;
4124 struct SOFT3D_texture
*ST
=SC
->state
.ST
;
4125 UBYTE FillMode
,EdgeMode
,TexEnvMode
,BlendMode
,UseFog
,UseGouraud
,UseBigTex
,UseTex24
,UseBuffer
;
4127 SFUNCTION(SOFT3D_SetDrawFunctions
)
4129 /* We may change those state values for a faster soft-rendering */
4131 TexEnvMode
=SC
->state
.TexEnvMode
;
4132 if(!SC
->state
.UseTex
)
4134 BlendMode
=SC
->state
.BlendMode
;
4135 UseFog
=SC
->state
.UseFog
;
4136 UseGouraud
=SC
->state
.UseGouraud
;
4138 if(Wazp3D
->DebugSOFT3D
.ON
)
4139 Libprintf(" FlatRGBA: %ld %ld %ld %ld\n",(ULONG
)SC
->FlatRGBA
[0],(ULONG
)SC
->FlatRGBA
[1],(ULONG
)SC
->FlatRGBA
[2],(ULONG
)SC
->FlatRGBA
[3]);
4141 if(UseGouraud
==FALSE
) /* if truly want flat color*/
4144 if(Wazp3D
->TexMode
.ON
!=3) /* in this case flatcolor is already polygon's averagecolor */
4145 COPYRGBA(SC
->FlatRGBA
,SC
->state
.CurrentRGBA
); /* if true no-gouraud mode then flat-color come from current-color */
4148 if(!SC
->ColorChange
) /* then dont truly need gouraud shading */
4150 SREM(Gouraud to Flat
)
4151 UseGouraud
=FALSE
; /* then flat color come from point-color NOT from current-color */
4154 UseTex24
=FALSE
; /* default 32 bits color */
4156 if(SC
->state
.UseTex
)
4158 if(256<ST
->large
) UseBigTex
=TRUE
;
4159 if(256<ST
->high
) UseBigTex
=TRUE
;
4160 UseTex24
=(ST
->bits
==24); /* but the tex can be only 24 bits */
4163 if( (BlendMode
==BLENDFASTALPHA
) ou (BlendMode
==BLENDNOALPHA
) )
4164 if(TexEnvMode
>W3D_REPLACE
) /* if got a coloring function */
4165 if(SC
->ColorTransp
) /* that colorize in alpha (=make texture transparent)*/
4167 SREM(ColorTransp so really use BLENDALPHA
)
4168 BlendMode
=BLENDALPHA
; /* then use the tex as a true alpha one */
4172 if(Wazp3D
->QuakeMatrixPatch
.ON
) /* patch: for glmatrix transparency */
4173 if(BlendMode
==W3D_ONE_MINUS_SRC_ALPHA
*16 + W3D_SRC_ALPHA
)
4174 BlendMode
=W3D_SRC_ALPHA
*16 + W3D_ONE_MINUS_SRC_ALPHA
;
4178 /* if color is white dont do a stupid flat-color modulate on a texture = do nothing */
4179 if(TexEnvMode
>W3D_REPLACE
) /* with a coloring function */
4180 if(!SC
->ColorChange
)
4183 SREM(Color is white so no Coloring
)
4184 TexEnvMode
=W3D_REPLACE
;
4187 if(Wazp3D
->DebugTexColor
.ON
)
4188 if(SC
->state
.UseTex
)
4189 if(ST
!=NULL
) /* display the parameters as the texture color */
4191 SC
->FlatRGBA
[0]=ST
->Tnum
; SC
->FlatRGBA
[1]=TexEnvMode
; SC
->FlatRGBA
[2]=BlendMode
;
4192 TexEnvMode
=0; BlendMode
=BLENDREPLACE
; UseFog
=FALSE
; UseGouraud
=SC
->ColorChange
=FALSE
;
4196 FillMode
=SC
->state
.UseTex
*4 + UseGouraud
*2 + UseFog
*1;
4197 SC
->FunctionFill
=Functions
.Fill
[FillMode
];
4201 SC
->FunctionFill
=(HOOKEDFUNCTION
)Fill_BigTexPersp2_Gouraud_Fog
;
4204 SC
->FunctionFill
=(HOOKEDFUNCTION
)Fill_BigTexPersp2
;
4208 EdgeMode
=(SC
->state
.PerspMode
!=0)*8+FillMode
;
4209 SC
->FunctionEdge
=Functions
.Edge
[EdgeMode
];
4211 if(SC
->state
.PerspMode
==2)
4212 SC
->FunctionPoly
=(HOOKEDFUNCTION
)Poly_Persp2x2_Tex_Gouraud_Fog
;
4214 if(SC
->state
.PerspMode
==1)
4216 SC
->FunctionPoly
=(HOOKEDFUNCTION
)Poly_Persp1_Tex_Gouraud_Fog
;
4217 if(!SC
->state
.UseTex
)
4221 SC
->FunctionPoly
=(HOOKEDFUNCTION
)Poly_Persp1_Gouraud
;
4223 SC
->FunctionPoly
=(HOOKEDFUNCTION
)Poly_Persp1_Flat
;
4225 if(SC
->state
.UseTex
)
4228 SC
->FunctionPoly
=(HOOKEDFUNCTION
)Poly_Persp1_Tex
;
4231 if(SC
->state
.PerspMode
==0)
4233 SC
->FunctionPoly
=(HOOKEDFUNCTION
)Poly_Persp0_Tex_Gouraud_Fog
;
4234 if(!SC
->state
.UseTex
)
4238 SC
->FunctionPoly
=(HOOKEDFUNCTION
)Poly_Persp0_Gouraud
;
4240 SC
->FunctionPoly
=(HOOKEDFUNCTION
)Poly_Persp0_Flat
;
4242 if(SC
->state
.UseTex
)
4245 SC
->FunctionPoly
=(HOOKEDFUNCTION
)Poly_Persp0_Tex
;
4248 SC
->FunctionZtest
=Functions
.Ztest
[SC
->state
.ZMode
];
4249 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_znever_update
)
4250 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zless
)
4251 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zgequal
)
4252 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zlequal
)
4253 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zgreater
)
4254 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_znotequal
)
4255 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zequal
)
4256 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zalways
)
4258 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_znever_update
)
4259 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zless_update
)
4260 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zgequal_update
)
4261 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zlequal_update
)
4262 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zgreater_update
)
4263 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_znotequal_update
)
4264 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zequal_update
)
4265 SINFO((void *)SC
->FunctionZtest
,(void *)Ztest_zalways_update
)
4267 SC
->FunctionIn
=(HOOKEDFUNCTION
)SC
->FunctionBitmapIn
;
4268 SC
->FunctionTexEnv
=NULL
;
4269 SC
->FunctionBlend
=NULL
;
4270 SC
->FunctionBlendFast
=NULL
;
4271 SC
->FunctionFog
=NULL
;
4272 SC
->FunctionFilter
=NULL
;
4273 SC
->FunctionSepia
=NULL
;
4274 SC
->FunctionOut
=(HOOKEDFUNCTION
)SC
->FunctionBitmapOut
;
4276 /* FunctionTexEnv */
4277 SC
->FunctionTexEnv
=Functions
.TexEnv
[TexEnvMode
*2+!UseTex24
];
4280 SC
->SrcFunc
=BlendMode
/16; SC
->DstFunc
=BlendMode
-SC
->SrcFunc
*16;
4283 if(SC
->FunctionTexEnv
==NULL
) /* if no function to convert a 24bits tex to 32bits color with alpha*/
4285 SREM( tex dont have alpha
)
4286 if(SC
->SrcFunc
==W3D_SRC_ALPHA
) SC
->SrcFunc
=W3D_ONE
;
4287 if(SC
->SrcFunc
==W3D_ONE_MINUS_SRC_ALPHA
) SC
->SrcFunc
=W3D_ZERO
;
4288 if(SC
->SrcFunc
==W3D_SRC_ALPHA_SATURATE
) SC
->SrcFunc
=W3D_ONE
;
4289 if(SC
->DstFunc
==W3D_SRC_ALPHA
) SC
->DstFunc
=W3D_ONE
;
4290 if(SC
->DstFunc
==W3D_ONE_MINUS_SRC_ALPHA
) SC
->DstFunc
=W3D_ZERO
;
4291 BlendMode
=(SC
->SrcFunc
*16 + SC
->DstFunc
);
4294 if(SC
->bits
==24) /* if screen dont have alpha*/
4296 SREM( screen dont have alpha
)
4297 if(SC
->SrcFunc
==W3D_DST_ALPHA
) SC
->SrcFunc
=W3D_ONE
;
4298 if(SC
->SrcFunc
==W3D_ONE_MINUS_DST_ALPHA
) SC
->SrcFunc
=W3D_ZERO
;
4299 if(SC
->DstFunc
==W3D_DST_ALPHA
) SC
->DstFunc
=W3D_ONE
;
4300 if(SC
->DstFunc
==W3D_ONE_MINUS_DST_ALPHA
) SC
->DstFunc
=W3D_ZERO
;
4301 BlendMode
=(SC
->SrcFunc
*16 + SC
->DstFunc
);
4304 if(SC
->state
.CurrentRGBA
[3]==255) /* if current-color dont have alpha*/
4306 SREM( CurrentRGBA dont have alpha
)
4307 if(SC
->SrcFunc
==W3D_CONSTANT_ALPHA
) SC
->SrcFunc
=W3D_ONE
;
4308 if(SC
->SrcFunc
==W3D_ONE_MINUS_CONSTANT_ALPHA
) SC
->SrcFunc
=W3D_ZERO
;
4309 if(SC
->DstFunc
==W3D_CONSTANT_ALPHA
) SC
->DstFunc
=W3D_ONE
;
4310 if(SC
->DstFunc
==W3D_ONE_MINUS_CONSTANT_ALPHA
) SC
->DstFunc
=W3D_ZERO
;
4311 BlendMode
=(SC
->SrcFunc
*16 + SC
->DstFunc
);
4314 SC
->FunctionBlend
=(HOOKEDFUNCTION
)PixelsBlendFunctionAll
; /* default is an universal (slow) blend function */
4315 SC
->FunctionBlendFast
=(HOOKEDFUNCTION
)Functions
.BlendFast
[BlendMode
];
4318 UseBuffer
=(SC
->FunctionOut
!=NULL
);
4319 if(BlendMode
==BLENDREPLACE
)
4321 SC
->FunctionBlend
=(HOOKEDFUNCTION
)PixelsColorToImage
;
4323 SC
->FunctionBlend
=(HOOKEDFUNCTION
)PixelsColorToBuffer
;
4325 if(TexEnvMode
==W3D_REPLACE
) /* if no texenv function to convert a 24bits tex to 32bits color*/
4327 SC
->FunctionTexEnv
= NULL
; /* FunctionTexEnv==FunctionBlend==REPLACE */
4330 SC
->FunctionBlend
=(HOOKEDFUNCTION
)PixelsTex24ToImage
;
4332 SC
->FunctionBlend
=(HOOKEDFUNCTION
)PixelsTex24ToBuffer
;
4336 SC
->FunctionBlend
=(HOOKEDFUNCTION
)PixelsTex32ToImage
;
4338 SC
->FunctionBlend
=(HOOKEDFUNCTION
)PixelsTex32ToBuffer
;
4340 SC
->FunctionIn
=NULL
; /* not need to read Image's pixels = : they are all replaced */
4344 if(Wazp3D
->DebugSOFT3D
.ON
)
4345 Libprintf("Functions set with TexEnvMode%ld BlendMode%ld\n",(ULONG
)TexEnvMode
,(ULONG
)BlendMode
);
4350 SC
->FunctionFog
=(HOOKEDFUNCTION
)PixelsFogToImage
;
4352 SC
->FunctionFog
=(HOOKEDFUNCTION
)PixelsFogToBuffer
;
4356 /* FunctionFilter */
4357 if(Wazp3D
->UseFiltering
.ON
)
4359 SC
->FunctionFilter
=(HOOKEDFUNCTION
)PixelsFilterToImage
;
4361 SC
->FunctionFilter
=(HOOKEDFUNCTION
)PixelsFilterToBuffer
;
4365 if(Wazp3D
->DebugSepiaImage
.ON
)
4367 SC
->FunctionSepia
=(HOOKEDFUNCTION
)PixelsSepiaToImage
;
4369 SC
->FunctionSepia
=(HOOKEDFUNCTION
)PixelsSepiaToBuffer
;
4374 /* patch suggestion from "Cosmos" */
4375 if(SC
->FunctionIn
==NULL
)
4376 if(SC
->FunctionTexEnv
==NULL
)
4377 if(SC
->FunctionBlend
==(HOOKEDFUNCTION
)PixelsTex24ToBuffer
)
4378 if(SC
->FunctionFog
==NULL
)
4379 if(SC
->FunctionFilter
==NULL
)
4380 if(SC
->FunctionSepia
==NULL
)
4382 if(SC
->FunctionOut
==(HOOKEDFUNCTION
)PixelsOutBGRA
)
4384 SC
->FunctionBlend
=NULL
;
4385 SC
->FunctionOut
=(HOOKEDFUNCTION
)PixelsOutBGRAfromtex24
;
4387 if(SC
->FunctionOut
==(HOOKEDFUNCTION
)PixelsOutARGB
)
4389 SC
->FunctionBlend
=NULL
;
4390 SC
->FunctionOut
=(HOOKEDFUNCTION
)PixelsOutARGBfromtex24
;
4395 if(FillMode
==0) /* flat color like Blender gui */
4396 if(SC
->FunctionBlend
==NULL
) /* not transparent */
4398 if(SC
->FunctionOut
==(HOOKEDFUNCTION
)PixelsOutRGBA
)
4399 SC
->FunctionOut
=(HOOKEDFUNCTION
)PixelsOutRGBA_Flat
;
4400 if(SC
->FunctionOut
==(HOOKEDFUNCTION
)PixelsOutBGRA
)
4401 SC
->FunctionOut
=(HOOKEDFUNCTION
)PixelsOutBGRA_Flat
;
4402 if(SC
->FunctionOut
==(HOOKEDFUNCTION
)PixelsOutARGB
)
4403 SC
->FunctionOut
=(HOOKEDFUNCTION
)PixelsOutARGB_Flat
;
4404 if(SC
->FunctionOut
==(HOOKEDFUNCTION
)PixelsOutABGR
)
4405 SC
->FunctionOut
=(HOOKEDFUNCTION
)PixelsOutABGR_Flat
;
4408 ChangeSoftPoint(SC
);
4410 /*=============================================================*/
4411 void SOFT3D_Flush(APTR sc
)
4413 struct SOFT3D_context
*SC
=sc
;
4415 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
4416 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
4417 SFUNCTION(SOFT3D_Flush
)
4421 HARD3D_Flush(&SC
->HC
);
4426 /* Will draw what is in the Fragments Buffer */
4427 SC
->FragSize2
=(SC
->FragBufferDone
- SC
->FragBuffer
+ 3)/2;
4428 if(SC
->FragSize2
==0) {SREM( ==> No fragments to draw
);goto DrawFragBufferEnd
;}
4430 if(SC
->Image8
==NULL
) return;
4432 /* v52: add three (noop) fragments to FragBuffer so can do size2=(size + 1)/2 and so can process 2 (or even 4) Frags inside a loop */
4433 SC
->FragBufferDone
[0].Tex8
=SC
->NoopRGBA
; /* read the noop pixel as texture */
4434 SC
->FragBufferDone
[1].Tex8
=SC
->NoopRGBA
;
4435 SC
->FragBufferDone
[2].Tex8
=SC
->NoopRGBA
;
4436 SC
->FragBufferDone
[0].Image8
=SC
->NoopRGBA
; /* write it in noop pixel = do nothing with Image */
4437 SC
->FragBufferDone
[1].Image8
=SC
->NoopRGBA
;
4438 SC
->FragBufferDone
[2].Image8
=SC
->NoopRGBA
;
4440 if(SC
->FunctionIn
!=NULL
)
4442 SREM(Pass1
: FunctionIn
)
4443 /* cant print inside lockbitmap so print the functionIn/Out name here */
4444 SINFO((void *)SC
->FunctionIn
,(void *)NULL
)
4445 SINFO((void *)SC
->FunctionIn
,(void *)PixelsInBGRA
)
4446 SINFO((void *)SC
->FunctionIn
,(void *)PixelsInRGBA
)
4447 SINFO((void *)SC
->FunctionIn
,(void *)PixelsInARGB
)
4448 SINFO((void *)SC
->FunctionIn
,(void *)PixelsInABGR
)
4449 SINFO((void *)SC
->FunctionIn
,(void *)PixelsInRGB
)
4450 SINFO((void *)SC
->FunctionIn
,(void *)PixelsInBGR
)
4451 SINFO((void *)SC
->FunctionIn
,(void *)PixelsIn16
)
4452 SINFO((void *)SC
->FunctionIn
,(void *)PixelsIn8
)
4454 goto DrawFragBufferEnd
; /* if cant read pixels then cancel this drawing */
4456 SC
->FunctionIn(SC
); /* convert readed pixels to RGBA format. */
4460 if(SC
->FunctionTexEnv
!=NULL
)
4462 SREM(Pass2
: FunctionTexEnv (coloring
/light
) )
4463 SC
->FunctionTexEnv(SC
);
4466 if(SC
->FunctionBlend
!=NULL
)
4468 SREM(Pass3
: FunctionBlend (transparency
) )
4469 SC
->FunctionBlend(SC
);
4472 if(SC
->FunctionFog
!=NULL
)
4474 SREM(Pass4
: FunctionFog
)
4475 SC
->FunctionFog(SC
);
4478 if(SC
->FunctionFilter
!=NULL
)
4480 SREM(Pass
5: FunctionFilter
)
4481 SC
->FunctionFilter(SC
);
4484 if(SC
->FunctionSepia
!=NULL
)
4486 SREM(Pass
6: FunctionSepia
: debug effect
)
4487 SC
->FunctionSepia(SC
);
4490 if(SC
->FunctionOut
!=NULL
)
4492 SREM(Pass
7:FunctionOut
)
4493 /* cant print inside lockbitmap so print the functionIn/Out name here */
4494 SINFO((void *)SC
->FunctionOut
,(void *)NULL
)
4495 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutBGRA
)
4496 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutRGBA
)
4497 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutARGB
)
4498 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutABGR
)
4499 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutBGRA_Flat
)
4500 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutRGBA_Flat
)
4501 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutARGB_Flat
)
4502 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutABGR_Flat
)
4503 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutRGB
)
4504 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutBGR
)
4505 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOut16
)
4506 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOut8
)
4507 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutBGRAfromtex24
)
4508 SINFO((void *)SC
->FunctionOut
,(void *)PixelsOutARGBfromtex24
)
4511 SC
->FunctionOut(SC
);
4518 SC
->FragBufferDone
=SC
->FragBuffer
;
4521 /*=============================================================*/
4522 void DrawSimplePix(struct SOFT3D_context
*SC
,register union pixel3D
*P
)
4524 struct SOFT3D_texture
*ST
=SC
->state
.ST
;
4526 SFUNCTION(DrawPointSimplePIX
)
4527 if ( (P
->W
.x
< 0) ou (P
->W
.y
< 0) ou (SC
->large
<= P
->W
.x
) ou (SC
->high
<= P
->W
.y
))
4530 SC
->Pix
=&(SC
->edge1
[P
->W
.y
]);
4536 SC
->MM
=&ST
->MMs
[0]; /* default to biggest mipmap <=> never call FunctionFill with SC->MM=NULL*/
4538 SC
->FunctionFill(SC
);
4540 /*=============================================================*/
4541 void DrawPointPix(struct SOFT3D_context
*SC
)
4543 register union pixel3D
*P
=SC
->PolyPix
;
4544 register WORD
*PointLarge
=SC
->PointLarges
;
4545 register WORD xmin
,xmax
,ymin
,ymax
,y
;
4547 struct SOFT3D_texture
*ST
=SC
->state
.ST
;
4548 struct state3D flatstate
;
4551 SFUNCTION(DrawPointPIX
)
4552 SVAR(SC
->state
.PointSize
)
4553 SC
->ColorChange
=FALSE
;
4555 /* point as tex nofog nogouraud just color */
4556 flatstate
.ZMode
=SC
->state
.ZMode
;
4557 flatstate
.PointSize
=SC
->state
.PointSize
;
4558 flatstate
.LineSize
=SC
->state
.LineSize
;
4559 flatstate
.BlendMode
=SC
->state
.BlendMode
;
4561 flatstate
.TexEnvMode
=0;
4562 flatstate
.PerspMode
=0;
4563 flatstate
.CullingMode
=W3D_NOW
;
4564 flatstate
.UseGouraud
=FALSE
;
4565 flatstate
.UseTex
=FALSE
;
4566 flatstate
.UseFog
=FALSE
;
4568 flatstate
.Changed
=TRUE
;
4570 SOFT3D_SetDrawState(SC
,&flatstate
);
4572 COPYRGBA(SC
->FlatRGBA
,SC
->PolyP
->RGBA
);
4574 if(SC
->state
.PointSize
==1.0)
4575 {DrawSimplePix(SC
,P
);return;}
4577 R
=SC
->state
.PointSize
/2+1;
4582 if ( (P
->W
.x
<xmin
) ou (P
->W
.y
<ymin
) ou (xmax
<=P
->W
.x
) ou (ymax
<=P
->W
.y
))
4585 P
->W
.y
=P
->W
.y
- SC
->state
.PointSize
/2.0;
4586 SC
->Pix
=&(SC
->edge1
[P
->W
.y
]);
4587 SC
->PolyHigh
=SC
->state
.PointSize
;
4591 COPYPIX(&SC
->Pix
[y
],P
);
4592 SC
->Pix
[y
].W
.large
=PointLarge
[y
];
4593 SC
->Pix
[y
].W
.x
=SC
->Pix
[y
].W
.x
- PointLarge
[y
]/2;
4597 SC
->MM
=&ST
->MMs
[0]; /* default to biggest mipmap <=> never call FunctionFill with SC->MM=NULL*/
4598 SC
->FunctionFill(SC
);
4600 /*=============================================================*/
4601 void DoDeltasUV(union pixel3D
*P1
,union pixel3D
*P2
)
4603 /* V44: Compute a quadratic approximation of texture to emulate perspective */
4604 double a
,b
,z0
,z2
,n
,dt
,rz4dt
;
4605 double u0
,u2
,du
,ddu
;
4606 double v0
,v2
,dv
,ddv
;
4609 if(P1
->L
.w
==P2
->L
.w
)
4611 P1
->L
.du
=(P2
->L
.u
- P1
->L
.u
)/n
;
4612 P1
->L
.dv
=(P2
->L
.v
- P1
->L
.v
)/n
;
4613 P1
->L
.ddu
=P1
->L
.ddv
=0;
4626 rz4dt
= (4.0*dt
*z0
) / (z0
+ z2
) ;
4627 a
= ( -rz4dt
+dt
+dt
) / (n
*n
) ;
4628 b
= ( +rz4dt
-dt
) / (n
) ;
4633 rz4dt
= (4.0*dt
*z0
) / (z0
+ z2
) ;
4634 a
= ( -rz4dt
+dt
+dt
) / (n
*n
) ;
4635 b
= ( +rz4dt
-dt
) / (n
) ;
4639 /* store ddu ddv du dv as LONG */
4646 /*=============================================================*/
4647 void Poly_Persp0_Tex(struct SOFT3D_context
*SC
)
4649 register union pixel3D
*P1
=SC
->P1
;
4650 register union pixel3D
*P2
=SC
->P2
;
4651 register LONG high
=SC
->PolyHigh
;
4653 register WORD large
,maxlarge
,maxn
;
4654 union pixel3D DeltaX
;
4656 SFUNCTION(Poly_Persp0_Tex
)
4658 NLOOP(high
) /* trouver le large max du polygone = meilleur delta */
4660 large
=P2
->W
.x
- P1
->W
.x
; P1
->W
.large
=large
;
4662 if(maxlarge
< large
)
4663 {maxn
=n
; maxlarge
=large
;}
4668 /* compute best delta */
4674 DeltaX
.L
.dz
=(P2
->L
.z
- P1
->L
.z
)/maxlarge
;
4675 DeltaX
.L
.du
=(P2
->L
.u
- P1
->L
.u
)/maxlarge
;
4676 DeltaX
.L
.dv
=(P2
->L
.v
- P1
->L
.v
)/maxlarge
;
4686 /* and copy same delta for all segments */
4690 P1
->L
.dz
=DeltaX
.L
.dz
;
4691 P1
->L
.du
=DeltaX
.L
.du
;
4692 P1
->L
.dv
=DeltaX
.L
.dv
;
4700 SC
->FunctionFill(SC
);
4702 /*=============================================================*/
4703 void Poly_Persp0_Gouraud(struct SOFT3D_context
*SC
)
4705 register union pixel3D
*P1
=SC
->P1
;
4706 register union pixel3D
*P2
=SC
->P2
;
4707 register LONG high
=SC
->PolyHigh
;
4709 register WORD large
,maxlarge
,maxn
;
4710 union pixel3D DeltaX
= {};
4712 SFUNCTION(Poly_Persp0_Gouraud
)
4714 NLOOP(high
) /* trouver le large max du polygone = meilleur delta */
4716 large
=P2
->W
.x
- P1
->W
.x
; P1
->W
.large
=large
;
4718 if(maxlarge
< large
)
4719 {maxn
=n
; maxlarge
=large
;}
4723 /* compute best delta */
4728 DeltaX
.L
.dz
=(P2
->L
.z
- P1
->L
.z
)/maxlarge
;
4729 DeltaX
.L
.dR
=(P2
->L
.R
- P1
->L
.R
)/maxlarge
;
4730 DeltaX
.L
.dG
=(P2
->L
.G
- P1
->L
.G
)/maxlarge
;
4731 DeltaX
.L
.dB
=(P2
->L
.B
- P1
->L
.B
)/maxlarge
;
4732 DeltaX
.L
.dA
=(P2
->L
.A
- P1
->L
.A
)/maxlarge
;
4735 /* and copy same delta for all segments */
4739 P1
->L
.dz
=DeltaX
.L
.dz
;
4740 P1
->L
.dR
=DeltaX
.L
.dR
;
4741 P1
->L
.dG
=DeltaX
.L
.dG
;
4742 P1
->L
.dB
=DeltaX
.L
.dB
;
4743 P1
->L
.dA
=DeltaX
.L
.dA
;
4748 SC
->FunctionFill(SC
);
4750 /*=============================================================*/
4751 void Poly_Persp0_Flat(struct SOFT3D_context
*SC
)
4753 register union pixel3D
*P1
=SC
->P1
;
4754 register union pixel3D
*P2
=SC
->P2
;
4755 register LONG high
=SC
->PolyHigh
;
4757 register WORD large
;
4759 SFUNCTION(Poly_Persp0_Flat
)
4760 /* compute a delta per segment */
4763 large
=P2
->W
.x
- P1
->W
.x
; P1
->W
.large
=large
;
4767 P1
->L
.dz
=(P2
->L
.z
- P1
->L
.z
)/large
;
4773 SC
->FunctionFill(SC
);
4775 /*=============================================================*/
4776 void Poly_Persp0_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
)
4778 register union pixel3D
*P1
=SC
->P1
;
4779 register union pixel3D
*P2
=SC
->P2
;
4780 register LONG high
=SC
->PolyHigh
;
4782 register WORD large
,maxlarge
,maxn
;
4783 union pixel3D DeltaX
= {};
4785 SFUNCTION(Poly_Persp0_Tex_Gouraud_Fog
)
4787 NLOOP(high
) /* trouver le large max du polygone = meilleur delta */
4789 large
=P2
->W
.x
- P1
->W
.x
; P1
->W
.large
=large
;
4791 if(maxlarge
< large
)
4792 {maxn
=n
; maxlarge
=large
;}
4796 /* compute best delta */
4801 DeltaX
.L
.dz
=(P2
->L
.z
- P1
->L
.z
)/maxlarge
;
4802 DeltaX
.L
.du
=(P2
->L
.u
- P1
->L
.u
)/maxlarge
;
4803 DeltaX
.L
.dv
=(P2
->L
.v
- P1
->L
.v
)/maxlarge
;
4804 DeltaX
.L
.dR
=(P2
->L
.R
- P1
->L
.R
)/maxlarge
;
4805 DeltaX
.L
.dG
=(P2
->L
.G
- P1
->L
.G
)/maxlarge
;
4806 DeltaX
.L
.dB
=(P2
->L
.B
- P1
->L
.B
)/maxlarge
;
4807 DeltaX
.L
.dA
=(P2
->L
.A
- P1
->L
.A
)/maxlarge
;
4808 DeltaX
.L
.dF
=(P2
->L
.F
- P1
->L
.F
)/maxlarge
;
4811 /* and copy same delta for all segments */
4815 P1
->L
.dz
=DeltaX
.L
.dz
;
4816 P1
->L
.du
=DeltaX
.L
.du
;
4817 P1
->L
.dv
=DeltaX
.L
.dv
;
4818 P1
->L
.dR
=DeltaX
.L
.dR
;
4819 P1
->L
.dG
=DeltaX
.L
.dG
;
4820 P1
->L
.dB
=DeltaX
.L
.dB
;
4821 P1
->L
.dA
=DeltaX
.L
.dA
;
4822 P1
->L
.dF
=DeltaX
.L
.dF
;
4830 SC
->FunctionFill(SC
);
4832 /*=============================================================*/
4833 void Poly_Persp1_Tex(struct SOFT3D_context
*SC
)
4835 register union pixel3D
*P1
=SC
->P1
;
4836 register union pixel3D
*P2
=SC
->P2
;
4837 register LONG high
=SC
->PolyHigh
;
4839 register WORD large
;
4841 SFUNCTION(Poly_Persp1_Tex
)
4842 /* compute a delta per segment */
4845 large
=P2
->W
.x
- P1
->W
.x
; P1
->W
.large
=large
;
4850 P1
->L
.dz
=(P2
->L
.z
- P1
->L
.z
)/large
;
4851 P1
->L
.du
=(P2
->L
.u
- P1
->L
.u
)/large
;
4852 P1
->L
.dv
=(P2
->L
.v
- P1
->L
.v
)/large
;
4861 SC
->FunctionFill(SC
);
4863 /*=============================================================*/
4864 void Poly_Persp1_Gouraud(struct SOFT3D_context
*SC
)
4866 register union pixel3D
*P1
=SC
->P1
;
4867 register union pixel3D
*P2
=SC
->P2
;
4868 register LONG high
=SC
->PolyHigh
;
4870 register WORD large
;
4872 SFUNCTION(Poly_Persp1_Gouraud
)
4873 /* compute a delta per segment */
4876 large
=P2
->W
.x
- P1
->W
.x
; P1
->W
.large
=large
;
4880 P1
->L
.dz
=(P2
->L
.z
- P1
->L
.z
)/large
;
4881 P1
->L
.dR
=(P2
->L
.R
- P1
->L
.R
)/large
;
4882 P1
->L
.dG
=(P2
->L
.G
- P1
->L
.G
)/large
;
4883 P1
->L
.dB
=(P2
->L
.B
- P1
->L
.B
)/large
;
4884 P1
->L
.dA
=(P2
->L
.A
- P1
->L
.A
)/large
;
4890 SC
->FunctionFill(SC
);
4892 /*=============================================================*/
4893 void Poly_Persp1_Flat(struct SOFT3D_context
*SC
)
4895 register union pixel3D
*P1
=SC
->P1
;
4896 register union pixel3D
*P2
=SC
->P2
;
4897 register LONG high
=SC
->PolyHigh
;
4899 register WORD large
;
4901 SFUNCTION(Poly_Persp1_Flat
)
4902 /* compute a delta per segment */
4905 large
=P2
->W
.x
- P1
->W
.x
; P1
->W
.large
=large
;
4909 P1
->L
.dz
=(P2
->L
.z
- P1
->L
.z
)/large
;
4915 SC
->FunctionFill(SC
);
4917 /*=============================================================*/
4918 void Poly_Persp1_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
)
4920 register union pixel3D
*P1
=SC
->P1
;
4921 register union pixel3D
*P2
=SC
->P2
;
4922 register LONG high
=SC
->PolyHigh
;
4924 register WORD large
;
4926 SFUNCTION(Poly_Persp1_Tex_Gouraud_Fog
)
4927 /* compute a delta per segment */
4930 large
=P2
->W
.x
- P1
->W
.x
; P1
->W
.large
=large
;
4934 P1
->L
.dz
=(P2
->L
.z
- P1
->L
.z
)/large
;
4935 P1
->L
.du
=(P2
->L
.u
- P1
->L
.u
)/large
;
4936 P1
->L
.dv
=(P2
->L
.v
- P1
->L
.v
)/large
;
4937 P1
->L
.dR
=(P2
->L
.R
- P1
->L
.R
)/large
;
4938 P1
->L
.dG
=(P2
->L
.G
- P1
->L
.G
)/large
;
4939 P1
->L
.dB
=(P2
->L
.B
- P1
->L
.B
)/large
;
4940 P1
->L
.dA
=(P2
->L
.A
- P1
->L
.A
)/large
;
4941 P1
->L
.dF
=(P2
->L
.F
- P1
->L
.F
)/large
;
4950 SC
->FunctionFill(SC
);
4952 /*=============================================================*/
4953 void Poly_Persp2_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
,union pixel3D
*P1
,union pixel3D
*P2
)
4955 register LONG high
=SC
->PolyHigh
;
4957 register WORD large
;
4959 SFUNCTION(Poly_Persp2_Tex_Gouraud_Fog
)
4961 /* compute a delta per segment */
4964 large
=P2
->W
.x
- P1
->W
.x
; P1
->W
.large
=large
;
4968 P1
->L
.dz
=(P2
->L
.z
- P1
->L
.z
)/large
;
4969 P1
->L
.dR
=(P2
->L
.R
- P1
->L
.R
)/large
;
4970 P1
->L
.dG
=(P2
->L
.G
- P1
->L
.G
)/large
;
4971 P1
->L
.dB
=(P2
->L
.B
- P1
->L
.B
)/large
;
4972 P1
->L
.dA
=(P2
->L
.A
- P1
->L
.A
)/large
;
4973 P1
->L
.dF
=(P2
->L
.F
- P1
->L
.F
)/large
;
4979 SC
->FunctionFill(SC
);
4981 /*=============================================================*/
4982 void Poly_Persp2x2_Tex_Gouraud_Fog(struct SOFT3D_context
*SC
)
4984 /* V44: convert polygon to 2 polygons for better perspective emulation */
4985 register union pixel3D
*P1
=SC
->P1
;
4986 register union pixel3D
*P2
=SC
->P2
;
4987 register union pixel3D
*PM
=&SC
->edgeM
[P1
->W
.y
];
4988 register LONG high
=SC
->PolyHigh
;
4992 SFUNCTION(Poly_Persp2x2_Tex_Gouraud_Fog
)
4993 if(SC
->PolyLarge
<10)
4994 {Poly_Persp1_Tex_Gouraud_Fog(SC
); return;}
4995 if(SC
->PolyLarge
<40)
4996 {Poly_Persp2_Tex_Gouraud_Fog(SC
,SC
->P1
,SC
->P2
);return;}
4998 /* compute center point PM */
5001 PM
->L
.x
=(P1
->L
.x
+ P2
->L
.x
)/2;
5002 PM
->L
.z
=(P1
->L
.z
+ P2
->L
.z
)/2.0;
5003 PM
->L
.w
=(P1
->L
.w
+ P2
->L
.w
)/2.0;
5004 PM
->L
.R
=(P1
->L
.R
+ P2
->L
.R
)/2;
5005 PM
->L
.G
=(P1
->L
.G
+ P2
->L
.G
)/2;
5006 PM
->L
.B
=(P1
->L
.B
+ P2
->L
.B
)/2;
5007 PM
->L
.A
=(P1
->L
.A
+ P2
->L
.A
)/2;
5008 PM
->L
.F
=(P1
->L
.F
+ P2
->L
.F
)/2;
5010 if(PM
->L
.w
==0.0) PM
->L
.w
=0.00001;
5011 u
= ( (P1
->L
.u
*P1
->L
.w
) + (P2
->L
.u
*P2
->L
.w
) ) /2.0 ;
5012 PM
->L
.u
=(u
/ PM
->L
.w
);
5014 v
= ( (P1
->L
.v
*P1
->L
.w
) + (P2
->L
.v
*P2
->L
.w
) ) /2.0 ;
5015 PM
->L
.v
=(v
/ PM
->L
.w
);
5017 PM
->W
.large
=P1
->W
.large
/2;
5018 P1
->W
.large
=P1
->W
.large
- PM
->W
.large
;
5025 PM
=&SC
->edgeM
[P1
->W
.y
];
5026 Poly_Persp2_Tex_Gouraud_Fog(SC
,P1
,PM
);
5027 Poly_Persp2_Tex_Gouraud_Fog(SC
,PM
,P2
);
5029 /*=============================================================*/
5030 void DrawSegmentPix(struct SOFT3D_context
*SC
,union pixel3D
*P1
,union pixel3D
*P2
)
5032 /* draw a simple horizontal line */
5033 register union pixel3D
*temp
;
5035 SFUNCTION(DrawSegmentPIX
)
5036 /* Trouver point P1 et point P2 des deux points de cette ligne */
5037 if (P1
->W
.x
> P2
->W
.x
)
5040 SC
->P1
=&(SC
->edge1
[P1
->W
.y
]);
5042 SC
->P2
=&(SC
->edge2
[P2
->W
.y
]);
5046 SC
->FunctionPoly(SC
);
5048 /*=============================================================*/
5049 void DrawLinePix(struct SOFT3D_context
*SC
)
5051 union pixel3D
*P1
=&SC
->PolyPix
[0];
5052 union pixel3D
*P2
=&SC
->PolyPix
[1];
5053 union pixel3D
*temp
;
5056 SFUNCTION(DrawLinePIX
)
5057 /* Trouver point min et point max des deux points P1&P2 de cette ligne */
5058 if (P1
->W
.y
> P2
->W
.y
)
5059 {P2
=&SC
->PolyPix
[0];P1
=&SC
->PolyPix
[1];}
5061 ordered
=P1
->W
.x
< P2
->W
.x
;
5063 n
= P2
->W
.x
- P1
->W
.x
; /* normal case : fill from left to right */
5065 n
= P1
->W
.x
- P2
->W
.x
; /* other case ... */
5066 SC
->PolyHigh
= P2
->W
.y
- P1
->W
.y
;
5067 n
= n
+ SC
->PolyHigh
;
5070 {DrawSimplePix(SC
,P1
);return;}
5073 {DrawSegmentPix(SC
,P1
,P2
);return;}
5075 /* Store the 2 points in an edge (edge1) */
5076 SC
->P1
=&SC
->edge1
[P1
->W
.y
]; /* draw edge from top(P1) to bottom (P2)*/
5077 SC
->P2
=&SC
->edge1
[P2
->W
.y
];
5080 SC
->FunctionEdge(SC
);
5083 P2
= SC
->P2
=&SC
->edge2
[P1
->W
.y
]; /* get the two edges (P1 & P2) both from top*/
5090 P2
->W
.x
++; /* so avoid to have a segment with large=0 */
5094 COPYPIX(P2
,P1
); /* copy last point of line identically */
5096 else /* not ordered */
5101 P1
->W
.x
++; /* so avoid to have a segment with large=0 */
5105 COPYPIX(P2
,P1
); /* copy last point of line identically */
5106 SWAP(SC
->P1
,SC
->P2
); /* swap P1 & P2 */
5111 SC
->FunctionPoly(SC
);
5113 /*=============================================================*/
5114 void DrawPolyPix(struct SOFT3D_context
*SC
)
5116 register union pixel3D
*P1
=NULL
;
5117 register union pixel3D
*P2
=NULL
;
5118 register WORD Pnb
=SC
->PolyPnb
;
5120 union pixel3D
*Pxmin
;
5121 union pixel3D
*Pxmax
;
5122 union pixel3D
*Pymin
;
5123 union pixel3D
*Pymax
;
5125 SFUNCTION(DrawPolyPix
)
5127 Pymin
=Pymax
=Pxmin
=Pxmax
=SC
->PolyPix
;
5130 /* Polygon loop : draw all edges */
5133 PrintPix(&SC
->PolyPix
[n
]);
5134 P1
=&(SC
->PolyPix
[n
]);
5135 P2
=&(SC
->PolyPix
[n
+1]);
5137 P2
=&(SC
->PolyPix
[0]);
5140 if (P1
->W
.x
< Pxmin
->W
.x
) Pxmin
=P1
;
5141 if (P2
->W
.x
< Pxmin
->W
.x
) Pxmin
=P2
;
5142 if (Pxmax
->W
.x
< P1
->W
.x
) Pxmax
=P1
;
5143 if (Pxmax
->W
.x
< P2
->W
.x
) Pxmax
=P2
;
5146 if(P1
->W
.y
!= P2
->W
.y
) /* skip horizontal edges */
5148 /* if P1 up and P2 down */
5149 if (P1
->W
.y
< P2
->W
.y
)
5151 if (P1
->W
.y
< Pymin
->W
.y
) Pymin
=P1
;
5152 if (Pymax
->W
.y
< P2
->W
.y
) Pymax
=P2
;
5153 SC
->P1
=&(SC
->edge1
[P1
->W
.y
]);
5154 SC
->P2
=&(SC
->edge1
[P2
->W
.y
]);
5155 COPYPIX(SC
->P1
,P1
); /* store the two points in this edge */
5160 /* if P2 up and P1 down */
5161 if (P2
->W
.y
< Pymin
->W
.y
) Pymin
=P2
;
5162 if (Pymax
->W
.y
< P1
->W
.y
) Pymax
=P1
;
5163 SC
->P1
=&(SC
->edge2
[P2
->W
.y
]);
5164 SC
->P2
=&(SC
->edge2
[P1
->W
.y
]);
5165 COPYPIX(SC
->P1
,P2
); /* store the two points in the other edge */
5168 /* draw this edge */
5169 SC
->FunctionEdge(SC
);
5172 /* all edges drawn */
5174 /* compute Poly sizes */
5175 SC
->PolyLarge
= Pxmax
->W
.x
- Pxmin
->W
.x
;
5176 SC
->PolyHigh
= Pymax
->W
.y
- Pymin
->W
.y
;
5178 /* if poly is only an horizontal line */
5181 DrawSegmentPix(SC
,Pxmin
,Pxmax
);
5185 /* eliminate poly if PolyLarge = 0 */
5186 if(SC
->PolyLarge
==0)
5189 /* patch: for TheVague if last line of screen then dont crop it */
5190 if(Pymax
->W
.y
==(SC
->high
-1))
5194 n
=(Pymin
->W
.y
+ Pymax
->W
.y
)/2; /* central line */
5196 if (SC
->edge1
[n
].L
.x
< SC
->edge2
[n
].L
.x
)
5198 SC
->P1
=&(SC
->edge1
[Pymin
->W
.y
]);
5199 SC
->P2
=&(SC
->edge2
[Pymin
->W
.y
]);
5203 SC
->P1
=&(SC
->edge2
[Pymin
->W
.y
]);
5204 SC
->P2
=&(SC
->edge1
[Pymin
->W
.y
]);
5207 SC
->FunctionPoly(SC
);
5209 SFUNCTION(-----------)
5211 /*==================================================================================*/
5212 void ChangeSoftFog(APTR sc
,UBYTE FogMode
,float FogZmin
,float FogZmax
,float FogDensity
,APTR fogrgba
)
5214 struct SOFT3D_context
*SC
=sc
;
5215 register float d
,z
,f
;
5218 UBYTE
*FogRGBA
=fogrgba
;
5222 register UBYTE
*Mul8
=SC
->Mul8
;
5223 register union oper3D Mul
;
5227 #define CLAMP(X,MIN,MAX) ((X)<(MIN)?(MIN):((X)>(MAX)?(MAX):(X)))
5229 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
5230 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
5231 SFUNCTION(ChangeSoftFog
)
5232 if(Wazp3D
->DebugSOFT3D
.ON
)
5243 if(FogZmin
< MINZ
) FogZmin
=MINZ
;
5244 if(MAXZ
<= FogZmax
) FogZmax
=MAXZ
;
5246 SC
->state
.FogMode
=FogMode
;
5247 SC
->state
.FogZmin
=FogZmin
;
5248 SC
->state
.FogZmax
=FogZmax
;
5249 SC
->state
.FogDensity
=FogDensity
;
5250 COPYRGBA(SC
->state
.FogRGBA
,FogRGBA
);
5255 z
=(((float)n
)/((float)FOGSIZE
));
5259 d
= 1.0F
/ (FogZmax
- FogZmin
);
5260 f
= (FogZmax
- z
) * d
;
5267 d
= -(FogDensity
*FogDensity
);
5275 f
=CLAMP(f
,0.0F
,1.0F
);
5276 f
=1.0-f
; /* alpha for fog */
5278 RGBA
=(UBYTE
*) &SC
->FogRGBAs
[n
];
5279 MUL8(A
,FogRGBA
[0],RGBA
[0])
5280 MUL8(A
,FogRGBA
[1],RGBA
[1])
5281 MUL8(A
,FogRGBA
[2],RGBA
[2])
5282 RGBA
[3]=ONE
-A
; /* alpha for background */
5284 if(Wazp3D
->DebugSOFT3D
.ON
) /* dont display all the fog values */
5295 /*================================================================*/
5296 void DrawPolyP(struct SOFT3D_context
*SC
)
5298 union pixel3D
*Pix
=SC
->PolyPix
;
5299 struct point3D
*P
=SC
->PolyP
;
5300 struct point3D PolyMin
;
5301 struct point3D PolyMax
;
5304 UBYTE ColorChange
,ColorTransp
,ColorWhite
,FlatChange
;
5307 if(Wazp3D
->DebugSOFT3D
.ON
) Libprintf("DrawPolyP Pnb %ld \n",(ULONG
)SC
->PolyPnb
);
5311 if(SC
->PolyPnb
> MAXPOLY
) {SREM(Poly has too much Points
!); return;}
5316 PolyMin
.x
=PolyMax
.x
=P
->x
;
5317 PolyMin
.y
=PolyMax
.y
=P
->y
;
5318 PolyMin
.z
=PolyMax
.z
=P
->z
;
5319 PolyMin
.u
=PolyMax
.u
=P
->u
;
5320 PolyMin
.v
=PolyMax
.v
=P
->v
;
5324 P
->y
=P
->y
+0.49; /* round to nearer pixel */
5327 if (P
->x
< PolyMin
.x
) PolyMin
.x
=P
->x
;
5328 if (PolyMax
.x
< P
->x
) PolyMax
.x
=P
->x
;
5329 if (P
->y
< PolyMin
.y
) PolyMin
.y
=P
->y
;
5330 if (PolyMax
.y
< P
->y
) PolyMax
.y
=P
->y
;
5331 if (P
->z
< PolyMin
.z
) PolyMin
.z
=P
->z
;
5332 if (PolyMax
.z
< P
->z
) PolyMax
.z
=P
->z
;
5334 if (P
->u
< PolyMin
.u
) PolyMin
.u
=P
->u
;
5335 if (PolyMax
.u
< P
->u
) PolyMax
.u
=P
->u
;
5336 if (P
->v
< PolyMin
.v
) PolyMin
.v
=P
->v
;
5337 if (PolyMax
.v
< P
->v
) PolyMax
.v
=P
->v
;
5344 if(Wazp3D
->QuakeMatrixPatch
.ON
)
5347 if(Wazp3D
->DebugSOFT3D
.ON
) { SVARF(PolyMin
.u
) SVARF(PolyMin
.v
) }
5348 PolyMin
.u
=FFLOOR(PolyMin
.u
);
5349 PolyMin
.v
=FFLOOR(PolyMin
.v
);
5350 if(Wazp3D
->DebugSOFT3D
.ON
) { SVARF(PolyMin
.u
) SVARF(PolyMin
.v
) }
5356 P
->u
=P
->u
- PolyMin
.u
;
5357 P
->v
=P
->v
- PolyMin
.v
;
5363 if(SC
->PolyPnb
== 2)
5370 {SREM( clipped away
); return;}
5377 FaceCCW
= ((P
[1].x
- P
[0].x
)*(P
[2].y
- P
[0].y
)-(P
[2].x
- P
[0].x
)*(P
[1].y
- P
[0].y
) < 0.0); /* formula from TinyGL */
5379 if(SC
->state
.CullingMode
==W3D_CCW
)
5381 {SREM( hided face
); return;}
5383 if(SC
->state
.CullingMode
==W3D_CW
)
5385 {SREM( hided face
); return;}
5389 if(NOTSAMERGBA(SC
->FlatRGBA
,SC
->PolyP
->RGBA
))
5390 {SREM(FlatRGBA changed
); FlatChange
=TRUE
;}
5392 COPYRGBA(SC
->FlatRGBA
,SC
->PolyP
->RGBA
); /* default: flat-color come from current points */
5393 if(Wazp3D
->TexMode
.ON
==3) /* in this case use face center as flat color */
5395 UVtoRGBA(SC
->state
.ST
,(P
[0].u
+P
[1].u
+P
[2].u
)/3.0,(P
[0].v
+P
[1].v
+P
[2].v
)/3.0,SC
->FlatRGBA
);
5405 if(Wazp3D
->TexMode
.ON
==2)
5406 UVtoRGBA(SC
->state
.ST
,P
->u
,P
->v
,P
->RGBA
);
5408 Pix
->L
.x
= 0; /* erase low parts */
5417 Pix
->W
.F
= P
->z
* (float)FOGSIZE
;
5419 if(P
->z
<MINZ
) Pix
->W
.F
=0;
5420 if(MAXZ
<P
->z
) Pix
->W
.F
=FOGSIZE
-1;
5423 Pix
->L
.u
= P
->u
* (256.0*65536.0); /* range UV to [0..256] + shift per 16 */
5424 Pix
->L
.v
= P
->v
* (256.0*65536.0);
5426 Pix
->W
.R
= P
->RGBA
[0];
5427 Pix
->W
.G
= P
->RGBA
[1];
5428 Pix
->W
.B
= P
->RGBA
[2];
5429 Pix
->W
.A
= P
->RGBA
[3];
5431 if(NOTSAMERGBA(SC
->PolyP
->RGBA
,P
->RGBA
)) /* if color truly change ==> do gouraud */
5432 {SREM(ColorChange
);ColorChange
=TRUE
;}
5434 if(SC
->PolyP
->RGBA
[3]!=P
->RGBA
[3]) /* if alpha change ==> do alpha */
5435 {SREM(ColorTransp
:A changed
);ColorTransp
=TRUE
;}
5437 if(Pix
->W
.x
< SC
->Pxmin
) SC
->Pxmin
=Pix
->W
.x
;
5438 if(SC
->Pxmax
< Pix
->W
.x
) SC
->Pxmax
=Pix
->W
.x
;
5439 if(Pix
->W
.y
< SC
->Pymin
) SC
->Pymin
=Pix
->W
.y
;
5440 if(SC
->Pymax
< Pix
->W
.y
) SC
->Pymax
=Pix
->W
.y
;
5441 if(ZVALUE
< SC
->Pzmin
) SC
->Pzmin
=ZVALUE
;
5442 if(SC
->Pzmax
< ZVALUE
) SC
->Pzmax
=ZVALUE
;
5448 if(SC
->PolyP
->RGBA
[3]!=255) /* if not solid ==> do alpha */
5449 {SREM(ColorTransp
:A
not solid
);ColorTransp
=TRUE
;}
5451 if(SC
->FlatRGBA
[0]==255)
5452 if(SC
->FlatRGBA
[1]==255)
5453 if(SC
->FlatRGBA
[2]==255)
5454 if(SC
->FlatRGBA
[3]==255)
5455 {SREM(ColorWhite
);ColorWhite
=TRUE
;}
5458 /* This face is inside a linear Fog ? */
5459 if(SC
->state
.UseFog
)
5460 if(SC
->state
.FogMode
==1)
5462 if(PolyMax
.z
< SC
->state
.FogZmin
) /* after start of fogging area ? */
5464 SREM(states changed
:Fog
)
5465 SC
->state
.UseFog
=FALSE
;
5466 SC
->state
.Changed
=TRUE
;
5469 if(Wazp3D
->DebugSOFT3D
.ON
)
5471 Libprintf("LinearFog:UseFog%ld. FogZmin FogZmax PolyZmin PolyZmax:",(ULONG
)SC
->state
.UseFog
);
5472 pf(SC
->state
.FogZmin
);pf(SC
->state
.FogZmax
);pf(PolyMin
.z
);pf(PolyMax
.z
);
5478 if(SC
->state
.TexEnvMode
!=W3D_REPLACE
)
5479 if( (FlatChange
) ou (SC
->ColorChange
!=ColorChange
) ou (SC
->ColorTransp
!=ColorTransp
) ou (SC
->ColorWhite
!=ColorWhite
) )
5481 SREM(states changed
:Color
)
5482 SC
->ColorChange
=ColorChange
;
5483 SC
->ColorTransp
=ColorTransp
;
5484 SC
->ColorWhite
=ColorWhite
;
5485 SC
->state
.Changed
=TRUE
;
5488 if(SC
->state
.Changed
)
5490 SOFT3D_SetDrawFunctions(SC
); /* draw functions still can change now if ColorChange ColorTransp UseFog just changed */
5491 SC
->state
.Changed
=FALSE
;
5496 case 1: DrawPointPix(SC
); break;
5497 case 2: DrawLinePix(SC
); break;
5498 default: DrawPolyPix(SC
); break;
5502 /*=============================================================*/
5503 void DrawTriP(struct SOFT3D_context
*SC
,register struct point3D
*A
,register struct point3D
*B
,register struct point3D
*C
)
5505 COPYP(&(SC
->PolyP
[0]),A
);
5506 COPYP(&(SC
->PolyP
[1]),B
);
5507 COPYP(&(SC
->PolyP
[2]),C
);
5511 /*=============================================================*/
5512 void UVtoRGBA(struct SOFT3D_texture
*ST
,float u
,float v
,UBYTE
*RGBA
)
5514 register UBYTE
*Tex8
;
5518 if(ST
==NULL
) return;
5523 Tex8
=ST
->MMs
[0].Tex8U
[u8
]+ST
->MMs
[0].Tex8V
[v8
];
5531 if(Wazp3D
->DebugSOFT3D
.ON
) PrintRGBA((UBYTE
*)RGBA
);
5533 /*=============================================================*/
5535 /*=============================================================*/
5536 void TexturePlot(struct SOFT3D_texture
*ST
,UWORD x
,UWORD y
,UBYTE
*ColorRGBA
)
5544 offset
=(ST
->large
*y
+ x
) * ST
->bits
/ 8;
5545 RGB
=&(ST
->pt
[offset
]);
5546 RGB
[0]=ColorRGBA
[0];
5547 RGB
[1]=ColorRGBA
[1];
5548 RGB
[2]=ColorRGBA
[2];
5550 RGB
[3]=ColorRGBA
[3];
5553 /*=============================================================*/
5554 void TextureBorder(struct SOFT3D_texture
*ST
)
5556 UBYTE GreenRGBA
[4]={0,255,0,255};
5557 UBYTE RedRGBA
[4]={255,0,0,255};
5562 TexturePlot(ST
,x
,0,RedRGBA
);
5563 TexturePlot(ST
,x
,ST
->high
-1,RedRGBA
);
5567 TexturePlot(ST
,0,y
,GreenRGBA
);
5568 TexturePlot(ST
,ST
->large
-1,y
,GreenRGBA
);
5572 /*=============================================================*/
5573 void TexturePrint(struct SOFT3D_texture
*ST
,WORD x
,WORD y
,UBYTE
*texte
)
5578 UBYTE Bit
[] = {128,64,32,16,8,4,2,1};
5580 #define FONTLARGE (128/8)
5586 if(32<c
) c
=c
-32; else c
=0;
5587 F
=&(font8x8
[(c AND
15) + (c
/16)*FONTLARGE
*FONTSIZE
]);
5592 RGBA
[0]=RGBA
[1]=RGBA
[2]=0;
5593 if (F
[0] AND Bit
[n
])
5594 RGBA
[0]=RGBA
[1]=RGBA
[2]=255;
5595 TexturePlot(ST
,x
+n
,y
+m
,RGBA
);
5604 /*================================================================*/
5605 void SOFT3D_DrawPrimitive(APTR sc
,APTR p
,ULONG Pnb
,ULONG primitive
)
5607 struct SOFT3D_context
*SC
=sc
;
5608 struct point3D
*P
=p
;
5612 struct SOFT3D_texture
*ST
=SC
->state
.ST
;
5614 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
5615 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
5616 /* If it's debug-texture then activate debugger to debug the full polygon */
5617 DebugState
=LibDebug
;
5619 if(Wazp3D
->DebugTexNumber
.ON
)
5620 if(ST
->Tnum
==DEBUGTNUM
)
5623 Libprintf("DrawPrimitive using DebugTexture %s===============\n",ST
->name
);
5629 if(Wazp3D
->DebugSOFT3D
.ON
)
5631 Libprintf("SOFT3D_DrawPrimitive Pnb %ld (%ld)\n",(ULONG
)Pnb
,(ULONG
)primitive
);
5633 if(ST
!=NULL
) Libprintf(" %s\n",ST
->name
);
5638 if(Wazp3D
->DebugContext
.ON
) /* backdoor: for debugging = display all the scene as lines */
5639 primitive
=W3D_PRIMITIVE_LINELOOP
;
5642 if(SC
->Image8
==NULL
)
5643 { REM(Image is lost
or freed
: cant draw
!!); return;} /* happen if SOFT3D_AllocImageBuffer() fail */
5645 SINFO(primitive
,W3D_PRIMITIVE_TRIANGLES
)
5646 SINFO(primitive
,W3D_PRIMITIVE_TRIFAN
)
5647 SINFO(primitive
,W3D_PRIMITIVE_TRISTRIP
)
5648 SINFO(primitive
,W3D_PRIMITIVE_POINTS
)
5649 SINFO(primitive
,W3D_PRIMITIVE_LINES
)
5650 SINFO(primitive
,W3D_PRIMITIVE_LINELOOP
)
5651 SINFO(primitive
,W3D_PRIMITIVE_LINESTRIP
)
5652 SINFO(primitive
,W3D_PRIMITIVE_POLYGON
)
5655 if(SC
->UseHard
) /* so dont use "soft" for drawing the primitive*/
5657 HARD3D_DrawPrimitive(&SC
->HC
,p
,Pnb
,primitive
);
5658 LibDebug
=DebugState
;
5662 #if defined(OS4COMPOSITING)
5665 COMP3D_DrawPrimitive(SC
,p
,Pnb
,primitive
);
5666 LibDebug
=DebugState
;
5672 if(primitive
==W3D_PRIMITIVE_TRIANGLES
)
5676 DrawTriP(SC
,&P
[3*n
+0],&P
[3*n
+1],&P
[3*n
+2]);
5680 if(Wazp3D
->PolyMode
.ON
==1)
5681 MaxPolyHack
=MAXPOLYHACK
;
5683 if(Wazp3D
->PolyMode
.ON
==2)
5684 MaxPolyHack
=MAXPOLYHACK2
;
5686 if(Pnb
<=MaxPolyHack
) /* a simple quad after a clipping in x y z can have now more than 4 points */
5688 if(primitive
==W3D_PRIMITIVE_TRIFAN
)
5689 primitive
=W3D_PRIMITIVE_POLYGON
;
5691 if(Wazp3D
->PolyMode
.ON
!=2)
5692 if(primitive
==W3D_PRIMITIVE_TRISTRIP
)
5696 COPYP(&(SC
->PolyP
[0]),&P
[0]);
5697 COPYP(&(SC
->PolyP
[1]),&P
[2]);
5698 COPYP(&(SC
->PolyP
[2]),&P
[1]);
5703 COPYP(&(SC
->PolyP
[0]),&P
[0]);
5704 COPYP(&(SC
->PolyP
[1]),&P
[2]);
5705 COPYP(&(SC
->PolyP
[2]),&P
[3]);
5706 COPYP(&(SC
->PolyP
[3]),&P
[1]);
5711 COPYP(&(SC
->PolyP
[0]),&P
[0]);
5712 COPYP(&(SC
->PolyP
[1]),&P
[2]);
5713 COPYP(&(SC
->PolyP
[2]),&P
[4]);
5714 COPYP(&(SC
->PolyP
[3]),&P
[3]);
5715 COPYP(&(SC
->PolyP
[4]),&P
[1]);
5720 COPYP(&(SC
->PolyP
[0]),&P
[0]);
5721 COPYP(&(SC
->PolyP
[1]),&P
[2]);
5722 COPYP(&(SC
->PolyP
[2]),&P
[4]);
5723 COPYP(&(SC
->PolyP
[3]),&P
[5]);
5724 COPYP(&(SC
->PolyP
[4]),&P
[3]);
5725 COPYP(&(SC
->PolyP
[5]),&P
[1]);
5730 COPYP(&(SC
->PolyP
[0]),&P
[0]);
5731 COPYP(&(SC
->PolyP
[1]),&P
[2]);
5732 COPYP(&(SC
->PolyP
[2]),&P
[4]);
5733 COPYP(&(SC
->PolyP
[3]),&P
[5]);
5734 COPYP(&(SC
->PolyP
[4]),&P
[6]);
5735 COPYP(&(SC
->PolyP
[5]),&P
[3]);
5736 COPYP(&(SC
->PolyP
[6]),&P
[1]);
5745 if(primitive
==W3D_PRIMITIVE_TRIFAN
)
5748 DrawTriP(SC
,&P
[0],&P
[n
-1],&P
[n
]);
5752 if(primitive
==W3D_PRIMITIVE_TRISTRIP
)
5755 if (n
&1) /* reverse vertex order */
5756 DrawTriP(SC
,&P
[n
-1],&P
[n
-2],&P
[n
-0]);
5758 DrawTriP(SC
,&P
[n
-2],&P
[n
-1],&P
[n
-0]);
5762 if(primitive
==W3D_PRIMITIVE_POINTS
)
5766 COPYP(&(SC
->PolyP
[0]),&P
[n
]);
5774 if(primitive
==W3D_PRIMITIVE_LINES
)
5779 COPYP(&(SC
->PolyP
[0]),&P
[2*n
]);
5780 COPYP(&(SC
->PolyP
[1]),&P
[2*n
+1]);
5787 if(primitive
==W3D_PRIMITIVE_LINELOOP
)
5792 COPYP(&(SC
->PolyP
[0]),&P
[n
]);
5793 COPYP(&(SC
->PolyP
[1]),&P
[n
+1]);
5798 COPYP(&(SC
->PolyP
[0]),&P
[nb
]);
5799 COPYP(&(SC
->PolyP
[1]),&P
[0 ]);
5805 if(primitive
==W3D_PRIMITIVE_LINESTRIP
)
5810 COPYP(&(SC
->PolyP
[0]),&P
[n
]);
5811 COPYP(&(SC
->PolyP
[1]),&P
[n
+1]);
5818 if(primitive
==W3D_PRIMITIVE_POLYGON
)
5822 COPYP(&(SC
->PolyP
[n
]),&P
[n
]);
5830 LibDebug
=DebugState
;
5832 /*=============================================================*/
5833 void ChangeSoftPoint(APTR sc
)
5835 struct SOFT3D_context
*SC
=sc
;
5836 register WORD
*PointLarge
;
5837 register WORD x
,y
,D
;
5839 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
5840 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
5842 SFUNCTION(ChangeSoftPoint
)
5843 PointLarge
=SC
->PointLarges
;
5844 D
=SC
->state
.PointSize
;
5845 SVAR(SC
->state
.PointSize
)
5848 if( ( (2*y
-D
)*(2*y
-D
) + 2*2*x
*x
) < D
*D
) PointLarge
[y
]=x
*2;
5850 /*==================================================================*/
5851 void *SOFT3D_CreateTexture(APTR sc
,APTR pt
,UWORD large
,UWORD high
,UWORD format
,UBYTE TexFlags
)
5853 struct SOFT3D_context
*SC
=sc
;
5854 struct SOFT3D_texture
*ST
;
5857 float TexelsPerU
,TexelsPerV
,nf
;
5858 UWORD BytesPerTexel
,BytesPerLine
,n
,m
,bits
;
5859 UBYTE BitmapName
[40];
5861 UBYTE UseMip
=TexFlags AND
1;
5864 #define W3D_R8G8B8 4
5865 #define W3D_R8G8B8A8 11
5868 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
5869 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
5870 SFUNCTION(SOFT3D_CreateTexture
)
5871 ST
=MYmalloc(sizeof(struct SOFT3D_texture
),"SOFT3D_texture");
5872 if(ST
==NULL
) return(NULL
);
5874 if(format
==W3D_R8G8B8
) bits
=24;
5875 if(format
==W3D_R8G8B8A8
) bits
=32;
5882 ST
->TexFlags
=TexFlags
;
5883 /* add to linkage */
5884 ST
->nextST
=SC
->firstST
;
5888 /* Create texture index */
5889 BytesPerTexel
=bits
/8;
5890 BytesPerLine
=ST
->large
*BytesPerTexel
;
5892 TexelsPerU
=((float)ST
->large
)/256.0;
5893 TexelsPerV
=((float)ST
->high
)/256.0;
5896 Tsize
=ST
->large
*ST
->high
*ST
->bits
/8;
5902 MMsize
=MAXTEXTURE
*MAXTEXTURE
*ST
->bits
/8;
5908 ST
->MMs
[m
].Tex8U
[n
]= (ULONG
)( BytesPerTexel
* (UWORD
)(TexelsPerU
*nf
));
5909 ST
->MMs
[m
].Tex8V
[n
]=Tex8V
+(ULONG
)( BytesPerLine
* (UWORD
)(TexelsPerV
*nf
));
5910 ST
->MMs
[m
].Tex8Ulow
[n
]= (ULONG
)( BytesPerTexel
* (UWORD
)(TexelsPerU
*nf
/256.0));
5911 ST
->MMs
[m
].Tex8Vlow
[n
]= (ULONG
)( BytesPerLine
* (UWORD
)(TexelsPerV
*nf
/256.0));
5913 ST
->MMs
[m
].Tex8Ulow
[n
]=0;
5915 ST
->MMs
[m
].Tex8Vlow
[n
]=0;
5920 if(Tsize
> MMsize
) /* for smaller texture-models use mipmaps */
5923 TexelsPerU
=TexelsPerU
/2.0;
5924 TexelsPerV
=TexelsPerV
/4.0;
5932 SC
->Tnb
++; ST
->Tnum
=SC
->Tnb
;
5933 Libsprintf((char*)ST
->name
,(char*)"Texture%ld_%ldX%ldX%ld.RAW",(ULONG
)ST
->Tnum
,(ULONG
)ST
->large
,(ULONG
)ST
->high
,(ULONG
)ST
->bits
);
5934 Libsprintf((char*)BitmapName
,(char*)"Tex%ld %ld",(ULONG
)ST
->Tnum
,(ULONG
)ST
->bits
);
5937 if(Wazp3D
->DebugTexNumber
.ON
)
5940 TexturePrint(ST
,0,ST
->high
/2,BitmapName
);
5946 if(SC
->UseHard
) HARD3D_CreateTexture(&SC
->HC
,&ST
->HT
,ST
->pt
,ST
->large
,ST
->high
,ST
->format
,ST
->TexFlags
);
5949 #if defined(OS4COMPOSITING)
5950 if(SC
->UseHard
) COMP3D_CreateTexture(SC
,ST
,ST
->pt
,ST
->large
,ST
->high
,ST
->format
,ST
->TexFlags
);
5954 if(Wazp3D
->DebugSOFT3D
.ON
)
5955 Libprintf("Tex<%s> ST%ld HT%ld gltex%ld\n",ST
->name
,(IPTR
)ST
,(IPTR
)&ST
->HT
,(ULONG
)ST
->HT
.gltex
);
5957 if(Wazp3D
->DebugST
.ON
)
5958 if(Wazp3D
->DebugSOFT3D
.ON
)
5959 LibAlert("Tex done...");
5962 return( (void *) ST
);
5964 /*==================================================================*/
5965 void SOFT3D_UpdateTexture(APTR sc
,APTR st
,APTR pt
)
5967 struct SOFT3D_context
*SC
=sc
;
5968 struct SOFT3D_texture
*ST
=st
;
5969 UBYTE UseMip
=ST
->TexFlags AND
1;
5972 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
5973 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
5974 SFUNCTION(SOFT3D_UpdateTexture
)
5976 {SREM(NULL ST
!!); return;}
5977 Tsize
=ST
->large
*ST
->high
*ST
->bits
/8;
5978 Libmemcpy(ST
->pt
,pt
,Tsize
);
5983 if(SC
->UseHard
) HARD3D_UpdateTexture(&SC
->HC
,&ST
->HT
,pt
,ST
->large
,ST
->high
,ST
->bits
);
5985 #if defined(OS4COMPOSITING)
5986 if(SC
->UseHard
) COMP3D_UpdateTexture(SC
,ST
,pt
,ST
->large
,ST
->high
,ST
->bits
);
5989 /*==================================================================*/
5990 void SOFT3D_FreeTexture(APTR sc
,APTR st
)
5992 struct SOFT3D_context
*SC
=sc
;
5993 struct SOFT3D_texture
*ST
=st
;
5994 struct SOFT3D_texture fakeST
;
5995 struct SOFT3D_texture
*thisST
=&fakeST
;
5998 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
5999 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
6000 SFUNCTION(SOFT3D_FreeTexture
)
6002 {SREM(NULL ST
!!); return;}
6005 thisST
->nextST
=SC
->firstST
;
6009 if(thisST
->nextST
==ST
)
6012 if(thisST
->nextST
==SC
->firstST
)
6013 SC
->firstST
=ST
->nextST
;
6015 thisST
->nextST
=ST
->nextST
;
6019 thisST
=thisST
->nextST
;
6024 if(SC
->UseHard
) HARD3D_FreeTexture(&SC
->HC
,&ST
->HT
);
6026 #if defined(OS4COMPOSITING)
6027 if(SC
->UseHard
) COMP3D_FreeTexture(SC
,ST
);
6029 if(SC
->state
.ST
==ST
)
6030 SC
->FragBufferDone
=SC
->FragBuffer
; /* cant draw fragments from a deleted texture */
6032 /*=================================================================*/
6033 void ClipPoint(struct SOFT3D_context
*SC
,struct point3D
*PN
,struct point3D
*P
,float t
)
6035 register float c0
,c1
;
6036 register float u0w
,v0w
,u1w
,v1w
;
6038 P
->x
= PN
[0].x
+ t
* (PN
[1].x
- PN
[0].x
) ;
6039 P
->y
= PN
[0].y
+ t
* (PN
[1].y
- PN
[0].y
) ;
6040 P
->z
= PN
[0].z
+ t
* (PN
[1].z
- PN
[0].z
) ;
6041 P
->w
= PN
[0].w
+ t
* (PN
[1].w
- PN
[0].w
) ;
6042 c0
=PN
[0].RGBA
[0]; c1
=PN
[1].RGBA
[0]; P
->RGBA
[0]=c0
+ t
* (c1
- c0
);
6043 c0
=PN
[0].RGBA
[1]; c1
=PN
[1].RGBA
[1]; P
->RGBA
[1]=c0
+ t
* (c1
- c0
);
6044 c0
=PN
[0].RGBA
[2]; c1
=PN
[1].RGBA
[2]; P
->RGBA
[2]=c0
+ t
* (c1
- c0
);
6045 c0
=PN
[0].RGBA
[3]; c1
=PN
[1].RGBA
[3]; P
->RGBA
[3]=c0
+ t
* (c1
- c0
);
6047 /* if want perspective then compute the new U V with a true-perspective */
6048 if(SC
->state
.PerspMode
!=0)
6051 u0w
=PN
[0].u
*PN
[0].w
;
6052 v0w
=PN
[0].v
*PN
[0].w
;
6053 u1w
=PN
[1].u
*PN
[1].w
;
6054 v1w
=PN
[1].v
*PN
[1].w
;
6055 P
->u
= (u0w
+ t
* (u1w
- u0w
) )/P
->w
;
6056 P
->v
= (v0w
+ t
* (v1w
- v0w
) )/P
->w
;
6060 /* else compute UV linearly as other coordinates */
6061 P
->u
= PN
[0].u
+ t
* (PN
[1].u
- PN
[0].u
) ;
6062 P
->v
= PN
[0].v
+ t
* (PN
[1].v
- PN
[0].v
) ;
6064 /*=================================================================*/
6065 #define CopyPoint(A) {COPYP(P,A); P++; NewPnb++; }
6066 #define SwapBuffers useT1=!useT1; if(useT1) {PN=T1; P=T2;} else {PN=T2; P=T1;}
6067 #define CLIPPOINT(val,limit) {ClipPoint(SC,PN,P,(limit - PN[0].val) / (PN[1].val - PN[0].val)); P->val=limit; }
6068 #define NEWCLIPPOINT(val,limit) {ClipPoint(SC,PN,P,(limit - PN[0].val) / (PN[1].val - PN[0].val)); P->val=limit; P++; NewPnb++; }
6069 /*=================================================================*/
6070 void ClipLine(struct SOFT3D_context
*SC
)
6072 struct point3D
*PN
=SC
->PolyP
;
6073 struct point3D
*P
; /* point to clip */
6074 register ULONG IsInside0
;
6075 register ULONG IsInside1
;
6077 IsInside0
=(SC
->ClipMin
.x
<= PN
[0].x
);
6078 IsInside1
=(SC
->ClipMin
.x
<= PN
[1].x
);
6079 if(!IsInside0
) if(!IsInside1
)
6080 { SC
->PolyPnb
=0; return; }
6081 if(IsInside0
!=IsInside1
)
6082 { if(IsInside0
) P
=&PN
[1]; else P
=&PN
[0]; CLIPPOINT(x
,SC
->ClipMin
.x
); }
6084 IsInside0
=(PN
[0].x
<= SC
->ClipMax
.x
);
6085 IsInside1
=(PN
[1].x
<= SC
->ClipMax
.x
);
6086 if(!IsInside0
) if(!IsInside1
)
6087 { SC
->PolyPnb
=0; return; }
6088 if(IsInside0
!=IsInside1
)
6089 { if(IsInside0
) P
=&PN
[1]; else P
=&PN
[0]; CLIPPOINT(x
,SC
->ClipMax
.x
); }
6091 IsInside0
=(SC
->ClipMin
.y
<= PN
[0].y
);
6092 IsInside1
=(SC
->ClipMin
.y
<= PN
[1].y
);
6093 if(!IsInside0
) if(!IsInside1
)
6094 { SC
->PolyPnb
=0; return; }
6095 if(IsInside0
!=IsInside1
)
6096 { if(IsInside0
) P
=&PN
[1]; else P
=&PN
[0]; CLIPPOINT(y
,SC
->ClipMin
.y
); }
6098 IsInside0
=(PN
[0].y
<= SC
->ClipMax
.y
);
6099 IsInside1
=(PN
[1].y
<= SC
->ClipMax
.y
);
6100 if(!IsInside0
) if(!IsInside1
)
6101 { SC
->PolyPnb
=0; return; }
6102 if(IsInside0
!=IsInside1
)
6103 { if(IsInside0
) P
=&PN
[1]; else P
=&PN
[0]; CLIPPOINT(y
,SC
->ClipMax
.y
); }
6107 /*=================================================================*/
6108 void ClipPoly(struct SOFT3D_context
*SC
)
6112 struct point3D
*T1
=(struct point3D
*)&SC
->T1
;
6113 struct point3D
*T2
=(struct point3D
*)&SC
->T2
;
6115 UBYTE IsInside
[MAXPOLY
];
6117 LONG Pnb
=SC
->PolyPnb
;
6121 if(Wazp3D
->DebugClipper
.ON
) REM(ClipPoly
)
6122 if(Pnb
>MAXPOLY
) return;
6128 Libmemcpy(PN
,SC
->PolyP
,Pnb
*PSIZE
);
6134 if(PN
[n
].x
<= SC
->ClipMax
.x
)
6135 { IsInside
[n
]=TRUE
; InsidePnb
++; }
6138 if(InsidePnb
==0) {if(Wazp3D
->DebugClipper
.ON
) REM(Outside Max
.x
) goto HideFace
;}
6142 if(Wazp3D
->DebugClipper
.ON
) REM(Clip Max
.x
)
6143 FaceClipped
=TRUE
; IsInside
[Pnb
]=IsInside
[0]; COPYP(&(PN
[Pnb
]),PN
);
6146 if(IsInside
[n
]==TRUE
)
6148 if(IsInside
[n
]!=IsInside
[n
+1])
6149 NEWCLIPPOINT(x
,SC
->ClipMax
.x
);
6156 /*=================================*/
6162 if(SC
->ClipMin
.x
<= PN
[n
].x
)
6163 { IsInside
[n
]=TRUE
; InsidePnb
++; }
6166 if(InsidePnb
==0) {if(Wazp3D
->DebugClipper
.ON
) REM(Outside Min
.x
) goto HideFace
;}
6170 if(Wazp3D
->DebugClipper
.ON
) REM(Clip Min
.x
)
6171 FaceClipped
=TRUE
; IsInside
[Pnb
]=IsInside
[0]; COPYP(&(PN
[Pnb
]),PN
);
6174 if(IsInside
[n
]==TRUE
)
6176 if(IsInside
[n
]!=IsInside
[n
+1])
6177 NEWCLIPPOINT(x
,SC
->ClipMin
.x
);
6183 /*=================================*/
6189 if(PN
[n
].y
<= SC
->ClipMax
.y
)
6190 { IsInside
[n
]=TRUE
; InsidePnb
++; }
6193 if(InsidePnb
==0) {if(Wazp3D
->DebugClipper
.ON
) REM(Outside Max
.y
) goto HideFace
;}
6197 if(Wazp3D
->DebugClipper
.ON
) REM(Clip Max
.y
)
6198 FaceClipped
=TRUE
; IsInside
[Pnb
]=IsInside
[0]; COPYP(&(PN
[Pnb
]),PN
);
6201 if(IsInside
[n
]==TRUE
)
6203 if(IsInside
[n
]!=IsInside
[n
+1])
6204 NEWCLIPPOINT(y
,SC
->ClipMax
.y
);
6210 /*=================================*/
6216 if(SC
->ClipMin
.y
<= PN
[n
].y
)
6217 { IsInside
[n
]=TRUE
; InsidePnb
++; }
6220 if(InsidePnb
==0) {if(Wazp3D
->DebugClipper
.ON
) REM(Outside Min
.y
) goto HideFace
;}
6224 if(Wazp3D
->DebugClipper
.ON
) REM(Clip Min
.y
)
6225 FaceClipped
=TRUE
; IsInside
[Pnb
]=IsInside
[0]; COPYP(&(PN
[Pnb
]),PN
);
6228 if(IsInside
[n
]==TRUE
)
6230 if(IsInside
[n
]!=IsInside
[n
+1])
6231 NEWCLIPPOINT(y
,SC
->ClipMin
.y
);
6237 /*=================================*/
6239 if(FaceClipped
==FALSE
) return;
6241 /* if clipped get the new PolyPnb & PolyP */
6243 if(useT1
) PN
=T1
; else PN
=T2
;
6245 if(Wazp3D
->DebugClipper
.ON
)
6247 SVARF(SC
->ClipMin
.x
);
6248 SVARF(SC
->ClipMax
.x
);
6249 SVARF(SC
->ClipMin
.y
);
6250 SVARF(SC
->ClipMax
.y
);
6251 SVARF(SC
->ClipMin
.z
);
6252 SVARF(SC
->ClipMax
.z
);
6254 if(SC
->state
.ST
!=NULL
)
6255 PrintST(SC
->state
.ST
);
6257 Wazp3D
->DebugPoint
.ON
=TRUE
;
6258 REM(CLIPPER
: original points
)
6260 PrintP(&SC
->PolyP
[n
]);
6261 REM(-------: clipped points
)
6264 REM(=======================)
6265 Wazp3D
->DebugPoint
.ON
=FALSE
;
6268 Libmemcpy(SC
->PolyP
,PN
,SC
->PolyPnb
*PSIZE
);
6274 /*=================================================================*/
6275 void ReduceBitmap(UBYTE
*pt
,UBYTE
*pt2
,UWORD large
,UWORD high
, WORD bits
,WORD ratio
)
6279 LONG P
,L
; /* bytesperpixel, bytesperline */
6286 if(Wazp3D
->DebugSOFT3D
.ON
) Libprintf("ReduceBitmap/%ld %ldX%ld %ldbits >from %ld to %ld\n",(ULONG
)ratio
,(ULONG
)large
,(ULONG
)high
,(ULONG
)bits
,(IPTR
)pt
,(IPTR
)pt2
);
6288 if(pt
==NULL
) return;
6289 if(pt2
==NULL
) return;
6307 offset
=L
*m
+P
*n
+L
*ratio
*y
+P
*ratio
*x
;
6323 if(Wazp3D
->DebugFunction
.ON
)
6333 /*==================================================================================*/
6334 void CreateMipmaps(struct SOFT3D_texture
*ST
)
6337 UWORD large
,high
,level
,reduction
;
6343 size
=ST
->large
* ST
->high
* ST
->bits
/ 8;
6344 ST
->ptmm
=MYmalloc(size
/3,"mipmaps"); /* size is mathematically false but allways fit */
6345 if(ST
->ptmm
==NULL
) return;
6352 if(Wazp3D
->DebugSOFT3D
.ON
) Libprintf("MipMap %ldX%ld = %ld (%ld)\n",(ULONG
)large
,(ULONG
)high
,(ULONG
)size
,(IPTR
)ptmm
);
6354 ReduceBitmap(ST
->pt
,ptmm
,ST
->large
,ST
->high
,ST
->bits
,reduction
);
6359 reduction
=reduction
*2;
6361 if (high
>0) goto next_mipmap
;
6363 /*==========================================================================*/
6364 void AntiAliasImage(void *image
,UWORD large
,UWORD high
)
6366 UBYTE AliasedLines
[4*MAXSCREEN
*2];
6367 register UWORD r
,g
,b
,x
,y
;
6368 register UBYTE
*L0
=(UBYTE
*)image
;
6371 register UBYTE
*line0
;
6372 register UBYTE
*line1
;
6376 if (large
>MAXSCREEN
) return;
6377 line0
=(UBYTE
*) &AliasedLines
[B32
*MAXSCREEN
*0];
6378 line1
=(UBYTE
*) &AliasedLines
[B32
*MAXSCREEN
*1];
6386 line0
[0+B32
]=L0
[0+B32
];
6387 line0
[1+B32
]=L0
[1+B32
];
6388 line0
[2+B32
]=L0
[2+B32
];
6392 line1
=(UBYTE
*)&AliasedLines
[B32
*MAXSCREEN
*1];
6397 line0
=(UBYTE
*) &AliasedLines
[B32
*MAXSCREEN
*0];
6398 line1
=(UBYTE
*) &AliasedLines
[B32
*MAXSCREEN
*1];
6403 r
=L1
[0+B32
]; r
=r
+r
; r
=r
+r
; r
=r
+r
;
6404 g
=L1
[1+B32
]; g
=g
+g
; g
=g
+g
; g
=g
+g
;
6405 b
=L1
[2+B32
]; b
=b
+b
; b
=b
+b
; b
=b
+b
;
6406 r
=r
+L0
[0+0]+L0
[0+B32
]+L0
[0+B32
*2]+L1
[0+0]+L1
[0+B32
*2]+L2
[0+0]+L2
[0+B32
]+L2
[0+B32
*2];
6407 g
=g
+L0
[1+0]+L0
[1+B32
]+L0
[1+B32
*2]+L1
[1+0]+L1
[1+B32
*2]+L2
[1+0]+L2
[1+B32
]+L2
[1+B32
*2];
6408 b
=b
+L0
[2+0]+L0
[2+B32
]+L0
[2+B32
*2]+L1
[2+0]+L1
[2+B32
*2]+L2
[2+0]+L2
[2+B32
]+L2
[2+B32
*2];
6414 L0
[0+B32
]=line0
[0+B32
];
6415 L0
[1+B32
]=line0
[1+B32
];
6416 L0
[2+B32
]=line0
[2+B32
];
6430 /*==========================================================================*/
6431 UBYTE
SOFT3D_DoUpdate(APTR sc
)
6433 struct SOFT3D_context
*SC
=sc
;
6435 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
6436 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
6437 SFUNCTION(SOFT3D_DoUpdate
)
6442 if(Wazp3D
->StepUpdate
.ON
)
6443 LibAlert("Update will occurs now !!");
6444 HARD3D_DoUpdate(&SC
->HC
);
6445 if(Wazp3D
->UseClearImage
.ON
)
6446 if(SC
->UseHard
) HARD3D_ClearImageBuffer(&SC
->HC
,0,0,SC
->large
,SC
->high
,SC
->state
.BackRGBA
);
6453 /* check is something new has been drawn ==> update */
6454 if(SC
->Pxmax
==0) return(FALSE
);
6455 if(SC
->Pymax
==0) return(FALSE
);
6459 if(SC
->Image8
==NULL
) return(FALSE
);
6463 if(Wazp3D
->StepUpdate
.ON
)
6464 LibAlert("Update will occurs now !!");
6466 if(SC
->ImageBuffer32
!=NULL
)
6468 SREM(Got an ImageBuffer32
)
6470 if(Wazp3D
->UseMinUpdate
.ON
)
6472 SC
->xUpdate
=SC
->Pxmin
; /* should also be used to clear the previous drawing */
6473 SC
->yUpdate
=SC
->Pymin
;
6474 SC
->largeUpdate
=SC
->Pxmax
-SC
->Pxmin
+1;
6475 SC
->highUpdate
=SC
->Pymax
-SC
->Pymin
+1;
6482 SC
->largeUpdate
=SC
->large
;
6483 SC
->highUpdate
=SC
->high
;
6487 if(Wazp3D
->DebugSOFT3D
.ON
)
6488 Libprintf("Updated Region from %ld %ld (%ld X %ld pixels) \n",(ULONG
)SC
->xUpdate
,(ULONG
)SC
->yUpdate
,(ULONG
)SC
->largeUpdate
,(ULONG
)SC
->highUpdate
);
6494 if(Wazp3D
->UseAntiImage
.ON
)
6495 AntiAliasImage(SC
->ImageBuffer32
,SC
->large
,SC
->high
);
6497 SREM(WriteImageBuffer
)
6498 if(0<SC
->largeUpdate
)
6499 if(SC
->largeUpdate
<=SC
->large
)
6500 if(0< SC
->highUpdate
)
6501 if(SC
->highUpdate
<=SC
->high
)
6505 SVAR(SC
->largeUpdate
)
6506 SVAR(SC
->highUpdate
)
6507 SC
->FunctionWriteImageBuffer(SC
); /* Do in fact WritePixelArray(ImageBuffer32) to rastport */
6508 if(Wazp3D
->UseClearImage
.ON
)
6509 SOFT3D_ClearImageBuffer(SC
,0,0,SC
->large
,SC
->high
,SC
->state
.BackRGBA
);
6513 SC
->Pxmin
=SC
->large
-1;
6514 SC
->Pymin
=SC
->high
-1;
6522 /*==========================================================================*/
6523 void SetDefaults(struct SOFT3D_context
*SC
)
6525 /* Set SOFT3D default values : notex nofog nozbuffer just white color */
6526 struct state3D defaultstate
;
6527 UBYTE WhiteRGBA
[4]={255,255,255,255};
6528 UBYTE BlackRGBA
[4]={0,0,0,255};
6531 defaultstate
.ZMode
=ZMODE(0,W3D_Z_ALWAYS
);
6532 defaultstate
.BlendMode
=BLENDREPLACE
;
6533 defaultstate
.UseGouraud
=FALSE
;
6534 defaultstate
.TexEnvMode
=0;
6535 defaultstate
.PerspMode
=0;
6536 defaultstate
.CullingMode
=W3D_NOW
;
6538 COPYRGBA(defaultstate
.FogRGBA
,WhiteRGBA
); /* default white fog */
6539 COPYRGBA(defaultstate
.CurrentRGBA
,WhiteRGBA
); /* default white color */
6540 COPYRGBA(defaultstate
.EnvRGBA
,WhiteRGBA
); /* default white env-color */
6541 COPYRGBA(defaultstate
.BackRGBA
,BlackRGBA
); /* default black background */
6543 defaultstate
.PointSize
=1;
6544 defaultstate
.LineSize
=1;
6546 defaultstate
.UseFog
=FALSE
;
6547 defaultstate
.FogMode
=0;
6548 defaultstate
.FogZmin
=MINZ
;
6549 defaultstate
.FogZmax
=MAXZ
;
6550 defaultstate
.FogDensity
=0.0;
6552 defaultstate
.UseTex
=FALSE
;
6553 defaultstate
.ST
=NULL
;
6554 defaultstate
.Changed
=TRUE
;
6556 SOFT3D_SetDrawState(SC
,&defaultstate
);
6558 /*==========================================================================*/
6559 void SOFT3D_SetBitmap(APTR sc
,void *bm
,APTR bmdata
,ULONG bmformat
,UWORD x
,UWORD y
,UWORD large
,UWORD high
)
6561 #if !defined(PIXFMT_ABGR32)
6562 #define PIXFMT_ABGR32 100
6563 #define PIXFMT_0RGB32 101
6564 #define PIXFMT_BGR032 102
6565 #define PIXFMT_RGB032 103
6566 #define PIXFMT_0BGR32 104
6569 struct SOFT3D_context
*SC
=sc
;
6571 ULONG Rbits
,Gbits
,Bbits
;
6572 ULONG Rpos
,Gpos
,Bpos
;
6573 ULONG Rlostbits
,Glostbits
,Blostbits
;
6576 BOOL PcOrder
,ChangeOrder
;
6582 if(!Wazp3D
->PrefsIsOpened
) /* if the user dont changing debug states */
6583 LibDebug
=Wazp3D
->DebugWazp3D
.ON
; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
6584 if(SC
==NULL
) return;
6585 SFUNCTION(SOFT3D_SetBitmap
)
6590 started
=(SC
->Image8
!=NULL
);
6593 SC
->rastport
.BitMap
=bm
;
6595 SC
->yoffset
=y
; /* only stored for WritePixelArray() */
6597 if(SC
->ImageBuffer32
!=NULL
)
6599 SREM(SetImage to ImageBuffer32
)
6600 SC
->bmformat
=PIXFMT_RGBA32
;
6601 SC
->FunctionBitmapIn
=NULL
; /* no need to read/write a bitmap in this case */
6602 SC
->FunctionBitmapOut
=NULL
;
6603 SetImage(SC
,0,0,large
,high
,32,(UBYTE
*)SC
->ImageBuffer32
);
6608 if(SC
->bmformat
==bmformat
)
6609 {bits
=SC
->bits
; goto setimageonly
;}
6611 SC
->bmformat
=bmformat
;
6613 /* Define the Pixels In/Out functions for this bitmap format */
6614 SREM(Bitmap format changed
)
6615 Rbits
=Gbits
=Bbits
=Rpos
=Gpos
=Bpos
=bits
=0;
6622 SC
->FunctionBitmapIn
=(HOOKEDFUNCTION
)PixelsInBGRA
;
6623 SC
->FunctionBitmapOut
=(HOOKEDFUNCTION
)PixelsOutBGRA
;
6624 Rbits
=8; Gbits
=8; Bbits
=8;
6625 Rpos
=8; Gpos
= 16; Bpos
= 24;
6631 SC
->FunctionBitmapIn
=(HOOKEDFUNCTION
)PixelsInRGBA
;
6632 SC
->FunctionBitmapOut
=(HOOKEDFUNCTION
)PixelsOutRGBA
;
6633 Rbits
=8; Gbits
=8; Bbits
=8;
6634 Rpos
=24; Gpos
= 16; Bpos
= 8;
6640 SC
->FunctionBitmapIn
=(HOOKEDFUNCTION
)PixelsInARGB
;
6641 SC
->FunctionBitmapOut
=(HOOKEDFUNCTION
)PixelsOutARGB
;
6642 Rbits
=8; Gbits
=8; Bbits
=8;
6643 Rpos
=16; Gpos
= 8; Bpos
= 0;
6649 SC
->FunctionBitmapIn
=(HOOKEDFUNCTION
)PixelsInABGR
;
6650 SC
->FunctionBitmapOut
=(HOOKEDFUNCTION
)PixelsOutABGR
;
6651 Rbits
=8; Gbits
=8; Bbits
=8;
6652 Rpos
=0; Gpos
= 8; Bpos
=16;
6658 SC
->FunctionBitmapIn
=(HOOKEDFUNCTION
)PixelsInRGB
;
6659 SC
->FunctionBitmapOut
=(HOOKEDFUNCTION
)PixelsOutRGB
;
6660 Rbits
=8; Gbits
=8; Bbits
=8;
6661 Rpos
=16; Gpos
= 8; Bpos
= 0;
6666 SC
->FunctionBitmapIn
=(HOOKEDFUNCTION
)PixelsInBGR
;
6667 SC
->FunctionBitmapOut
=(HOOKEDFUNCTION
)PixelsOutBGR
;
6668 Rbits
=8; Gbits
=8; Bbits
=8;
6669 Rpos
=0; Gpos
= 8; Bpos
= 16;
6675 Rbits
=5; Gbits
=5; Bbits
=5;
6676 Rpos
=10; Gpos
= 5; Bpos
= 0;
6681 Rbits
=5; Gbits
=6; Bbits
=5;
6682 Rpos
=11; Gpos
= 5; Bpos
= 0;
6687 Rbits
=5; Gbits
=5; Bbits
=5;
6688 Bpos
=10; Gpos
= 5; Rpos
= 0;
6693 Rbits
=5; Gbits
=6; Bbits
=5;
6694 Bpos
=11; Gpos
= 5; Rpos
= 0;
6699 case PIXFMT_RGB15PC
:
6700 Rbits
=5; Gbits
=5; Bbits
=5;
6701 Rpos
=10; Gpos
= 5; Bpos
= 0;
6705 case PIXFMT_RGB16PC
:
6706 Rbits
=5; Gbits
=6; Bbits
=5;
6707 Rpos
=11; Gpos
= 5; Bpos
= 0;
6711 case PIXFMT_BGR15PC
:
6712 Rbits
=5; Gbits
=5; Bbits
=5;
6713 Bpos
=10; Gpos
= 5; Rpos
= 0;
6717 case PIXFMT_BGR16PC
:
6718 Rbits
=5; Gbits
=6; Bbits
=5;
6719 Bpos
=11; Gpos
= 5; Rpos
= 0;
6725 Rbits
=3; Gbits
=3; Bbits
=2;
6726 Rpos
=5; Gpos
= 2; Bpos
= 0;
6729 SC
->FunctionBitmapIn
=(HOOKEDFUNCTION
)PixelsIn8
;
6730 SC
->FunctionBitmapOut
=(HOOKEDFUNCTION
)PixelsOut8
;
6734 Libprintf("WAZP3D/SOFT3D: Unknown bitmap format %ld (%ld X %ld)\n",bmformat
,large
,high
);
6752 SC
->FunctionBitmapIn
=(HOOKEDFUNCTION
)PixelsIn16
;
6753 SC
->FunctionBitmapOut
=(HOOKEDFUNCTION
)PixelsOut16
;
6756 ChangeOrder
= PcOrder
; /* if cpu is motorola need to change pc's pixel-formats */
6760 /* do the precalculated tables to convert 8/15/16 bits <-> 32bits */
6767 W
=((n
>>Rlostbits
)<<Rpos
);
6770 W
=((n
>>Glostbits
)<<Gpos
);
6773 W
=((n
>>Blostbits
)<<Bpos
);
6779 RGBA
=(UBYTE
*) &(SC
->B0toRGBA32
[n
]) ;
6780 RGBA
[0]=((B0
>>Rpos
)<<Rlostbits
);
6781 RGBA
[1]=((B0
>>Gpos
)<<Glostbits
);
6782 RGBA
[2]=((B0
>>Bpos
)<<Blostbits
);
6785 RGBA
=(UBYTE
*) &(SC
->B1toRGBA32
[n
]) ;
6786 RGBA
[0]=((B1
>>Rpos
)<<Rlostbits
);
6787 RGBA
[1]=((B1
>>Gpos
)<<Glostbits
);
6788 RGBA
[2]=((B1
>>Bpos
)<<Blostbits
);
6793 SWAP(SC
->RtoB0
[n
],SC
->RtoB1
[n
])
6794 SWAP(SC
->GtoB0
[n
],SC
->GtoB1
[n
])
6795 SWAP(SC
->BtoB0
[n
],SC
->BtoB1
[n
])
6796 SWAP(SC
->B0toRGBA32
[n
],SC
->B1toRGBA32
[n
])
6803 SREM(SetImage to bitmap data
)
6804 SetImage(SC
,x
,y
,large
,high
,bits
,bmdata
);
6808 if(SC
->UseHard
) HARD3D_SetBitmap(&SC
->HC
,bm
,SC
->Image8
,bmformat
,0,0,large
,high
);
6813 /*=============================================================*/
6814 void PixelsIn16(struct SOFT3D_context
*SC
)
6816 /* Convert 16bits -> buffer */
6817 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
6818 register ULONG size
=SC
->FragSize2
;
6819 register ULONG
*B0toRGBA32
=(ULONG
*)SC
->B0toRGBA32
;
6820 register ULONG
*B1toRGBA32
=(ULONG
*)SC
->B1toRGBA32
;
6821 register ULONG
*RGBA32
;
6825 RGBA32
=(ULONG
*)Frag
[0].BufferRGBA
;
6826 RGBA32
[0]=B0toRGBA32
[Frag
[0].Image8
[0]]+B1toRGBA32
[Frag
[0].Image8
[1]];
6828 RGBA32
=(ULONG
*)Frag
[1].BufferRGBA
;
6829 RGBA32
[0]=B0toRGBA32
[Frag
[1].Image8
[0]]+B1toRGBA32
[Frag
[1].Image8
[1]];
6834 /*=============================================================*/
6835 void PixelsOut16(struct SOFT3D_context
*SC
)
6837 /* Convert buffer -> 16bits */
6838 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
6839 register ULONG size
=SC
->FragSize2
;
6840 register UBYTE
*RGB
;
6841 register UBYTE
*RtoB0
=SC
->RtoB0
;
6842 register UBYTE
*GtoB0
=SC
->GtoB0
;
6843 register UBYTE
*BtoB0
=SC
->BtoB0
;
6844 register UBYTE
*RtoB1
=SC
->RtoB1
;
6845 register UBYTE
*GtoB1
=SC
->GtoB1
;
6846 register UBYTE
*BtoB1
=SC
->BtoB1
;
6850 RGB
=Frag
[0].BufferRGBA
;
6851 Frag
[0].Image8
[0]=RtoB0
[RGB
[0]]+GtoB0
[RGB
[1]]+BtoB0
[RGB
[2]];
6852 Frag
[0].Image8
[1]=RtoB1
[RGB
[0]]+GtoB1
[RGB
[1]]+BtoB1
[RGB
[2]];
6853 RGB
=Frag
[1].BufferRGBA
;
6854 Frag
[1].Image8
[0]=RtoB0
[RGB
[0]]+GtoB0
[RGB
[1]]+BtoB0
[RGB
[2]];
6855 Frag
[1].Image8
[1]=RtoB1
[RGB
[0]]+GtoB1
[RGB
[1]]+BtoB1
[RGB
[2]];
6860 /*=============================================================*/
6861 void PixelsIn8(struct SOFT3D_context
*SC
)
6863 /* Convert 8bits -> buffer */
6864 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
6865 register ULONG size
=SC
->FragSize2
;
6866 register ULONG
*B0toRGBA32
=(ULONG
*)SC
->B0toRGBA32
;
6867 register ULONG
*RGBA32
;
6871 RGBA32
=(ULONG
*)Frag
[0].BufferRGBA
;
6872 RGBA32
[0]=B0toRGBA32
[Frag
[0].Image8
[0]];
6874 RGBA32
=(ULONG
*)Frag
[1].BufferRGBA
;
6875 RGBA32
[0]=B0toRGBA32
[Frag
[1].Image8
[0]];
6880 /*=============================================================*/
6881 void PixelsOut8(struct SOFT3D_context
*SC
)
6883 /* Convert buffer -> 8bits */
6884 register struct fragbuffer3D
*Frag
=SC
->FragBuffer
;
6885 register ULONG size
=SC
->FragSize2
;
6886 register UBYTE
*RtoB
=SC
->RtoB0
;
6887 register UBYTE
*GtoB
=SC
->GtoB0
;
6888 register UBYTE
*BtoB
=SC
->BtoB0
;
6889 register UBYTE
*RGB
;
6893 RGB
=Frag
[0].BufferRGBA
;
6894 Frag
[0].Image8
[0]=RtoB
[RGB
[0]]+GtoB
[RGB
[1]]+BtoB
[RGB
[2]];
6895 RGB
=Frag
[1].BufferRGBA
;
6896 Frag
[1].Image8
[0]=RtoB
[RGB
[0]]+GtoB
[RGB
[1]]+BtoB
[RGB
[2]];
6901 /*==========================================================================*/
6902 BOOL
LockBM(struct SOFT3D_context
*SC
)
6905 UBYTE
*Image8
; /* = bitmap memory */
6907 if(SC
->ImageBuffer32
!=NULL
) /* So we dont write to a bitmap but to an RGBA buffer called "ImageBuffer32" */
6910 SC
->bmHandle
=LockBitMapTags((APTR
)SC
->bm
,LBMI_BASEADDRESS
,(IPTR
)&Image8
, TAG_DONE
);
6911 return(SC
->bmHandle
!=NULL
);
6916 /*==========================================================================*/
6917 void UnLockBM(struct SOFT3D_context
*SC
)
6920 if(SC
->ImageBuffer32
!=NULL
) /* So we dont write to a bitmap but to an RGBA buffer called "ImageBuffer32" */
6923 if(SC
->bmHandle
!=NULL
)
6924 UnLockBitMap(SC
->bmHandle
);
6927 /*=================================================================*/