www.pudn.com > LightTrack.rar > GraphicsPoly.cpp
/** 3DGPL *************************************************\ * () * * 2D graphics and 2D clipping extentions for shaded * * and textured polygons (has to be linked with regular * * routines). * * * * Ifdefs: * * _CI_ Colour/Intensity model; * * _RGB_ RGB model; * * _Z_BUFFER_ Depth array; * * _PAINTER_ Back front order. * * * * Defines: * * G_flat_polygon Regular polygon; * * G_shaded_polygon Shaded polygon; * * G_lin_textured_polygon Textured polygon (approx); * * G_prp_textured_polygon Textured polygon (true). * * * * Internals: * * GI_scan Scanning an edge; * * GI_boarder_array_init Init left/right boundaries. * * * * (c) 1995-98 Sergei Savchenko, (savs@cs.mcgill.ca) * \**********************************************************/ //GraphicsPoly.cpp #include "LightTrack.h" /* hardware specific stuff */ #include "Colour.h" /* colour and light */ #include "Clipper.h" /* 2D clipping */ #include "Graphics.h" /* 2D macros */ #include "Engine.h" /* M_LNG_SHADED */ #include/* INT_MAX and INT_MIN */ extern HW_pixel *G_c_buffer; /* the bitmap's bits */ extern int G_page_start; /* always 0 for _MONO_ */ #if defined(_Z_BUFFER_) extern int *G_z_buffer; /* Z buffer */ #endif #define G_LINEAR 32 /* interpolate for */ int G_miny,G_maxy; /* vertical boundaries */ int G_x_start[HW_SCREEN_Y_SIZE]; /* polygon's */ int G_x_end[HW_SCREEN_Y_SIZE]; /* horizontal boundaries */ HW_32_bit G_0_start[HW_SCREEN_Y_SIZE]; /* [32-G_P].[G_P] values */ HW_32_bit G_0_end[HW_SCREEN_Y_SIZE]; /* the thingie is to work faster */ HW_32_bit G_1_start[HW_SCREEN_Y_SIZE]; /* then multidimensional array */ HW_32_bit G_1_end[HW_SCREEN_Y_SIZE]; /* hope so, */ HW_32_bit G_2_start[HW_SCREEN_Y_SIZE]; HW_32_bit G_2_end[HW_SCREEN_Y_SIZE]; /* space for interpolating */ HW_32_bit G_3_start[HW_SCREEN_Y_SIZE]; /* Z R G B Tx Ty */ HW_32_bit G_3_end[HW_SCREEN_Y_SIZE]; HW_32_bit G_4_start[HW_SCREEN_Y_SIZE]; HW_32_bit G_4_end[HW_SCREEN_Y_SIZE]; HW_32_bit G_5_start[HW_SCREEN_Y_SIZE]; HW_32_bit G_5_end[HW_SCREEN_Y_SIZE]; HW_32_bit *G_start[C_MAX_DIMENSIONS]= {G_0_start,G_1_start,G_2_start,G_3_start,G_4_start,G_5_start}; HW_32_bit *G_end[C_MAX_DIMENSIONS]= {G_0_end,G_1_end,G_2_end,G_3_end,G_4_end,G_5_end}; #if defined(_CI_) #if defined(_Z_BUFFER_) /* Z I Tx Ty */ #define G_Z_INDX_START G_0_start /* indexed colour, z-buffer */ #define G_I_INDX_START G_1_start #define G_TX_INDX_START G_2_start #define G_TY_INDX_START G_3_start #define G_Z_INDX_END G_0_end /* indexed colour, z-buffer */ #define G_I_INDX_END G_1_end #define G_TX_INDX_END G_2_end #define G_TY_INDX_END G_3_end #endif #if defined(_PAINTER_) /* I Tx Ty */ #define G_I_INDX_START G_0_start /* indexed colour, painter */ #define G_TX_INDX_START G_1_start #define G_TY_INDX_START G_2_start #define G_I_INDX_END G_0_end /* indexed colour, painter */ #define G_TX_INDX_END G_1_end #define G_TY_INDX_END G_2_end #endif #endif #if defined(_RGB_) #if defined(_Z_BUFFER_) /* Z R G B Tx Ty */ #define G_Z_INDX_START G_0_start /* RGB colour, z-buffer */ #define G_R_INDX_START G_1_start #define G_G_INDX_START G_2_start #define G_B_INDX_START G_3_start #define G_TX_INDX_START G_4_start #define G_TY_INDX_START G_5_start #define G_Z_INDX_END G_0_end /* RGB colour, z-buffer */ #define G_R_INDX_END G_1_end #define G_G_INDX_END G_2_end #define G_B_INDX_END G_3_end #define G_TX_INDX_END G_4_end #define G_TY_INDX_END G_5_end #endif #if defined(_PAINTER_) /* R G B Tx Ty */ #define G_R_INDX_START G_0_start /* RGB colou, painter */ #define G_G_INDX_START G_1_start #define G_B_INDX_START G_2_start #define G_TX_INDX_START G_3_start #define G_TY_INDX_START G_4_start #define G_R_INDX_END G_0_end /* RGB colou, painter */ #define G_G_INDX_END G_1_end #define G_B_INDX_END G_2_end #define G_TX_INDX_END G_3_end #define G_TY_INDX_END G_4_end #endif #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * INTERNAL: Scan converting a N dimensional line. * * --------- * * SETS: G_x_start,G_x_end,G_start,G_end,G_miny,G_maxy * * ----- * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void GI_scan(int *edges,int dimension,int skip) { HW_32_bit cur_v[C_MAX_DIMENSIONS]; /* initial values for Z+ dims */ HW_32_bit inc_v[C_MAX_DIMENSIONS]; /* increment for Z+ dimensions */ int dx,dy,long_d,short_d; register int d,add_dh,add_dl; register int inc_xh,inc_yh,inc_xl,inc_yl; int x,y,i,j; int *v1,*v2; /* first and second vertices */ v1=edges; edges+=skip; v2=edges; /* length ints in each */ if(C_line_y_clipping(&v1,&v2,dimension)) /* vertical clipping */ { dx=*v2++; dy=*v2++; /* extracting 2-D coordinates */ x=*v1++; y=*v1++; /* v2/v1 point remaining dim-2 */ dimension-=2; if(y G_maxy) G_maxy=y; if(dy G_maxy) G_maxy=dy; /* updating vertical size */ dx-=x; dy-=y; /* ranges */ if(dx<0){dx=-dx; inc_xh=-1; inc_xl=-1;} /* making sure dx and dy >0 */ else { inc_xh=1; inc_xl=1; } /* adjusting increments */ if(dy<0){dy=-dy; inc_yh=-1; inc_yl=-1;} else { inc_yh=1; inc_yl=1; } if(dx>dy){long_d=dx;short_d=dy;inc_yl=0;} /* long range,&make sure either */ else {long_d=dy;short_d=dx;inc_xl=0;} /* x or y is changed in L case */ d=2*short_d-long_d; /* initial value of d */ add_dl=2*short_d; /* d adjustment for H case */ add_dh=2*(short_d-long_d); /* d adjustment for L case */ #if defined(_Z_BUFFER_) cur_v[0]=((HW_32_bit)v1[0])< 0) inc_v[0]=(((HW_32_bit)(v2[0]-v1[0]))< 0) inc_v[i]=((HW_32_bit)(v2[i]-v1[i]))/long_d; } for(i=0;i<=long_d;i++) /* for all points in long range */ { if(x =0){x+=inc_xh;y+=inc_yh;d+=add_dh;} /* previous point was H type */ else {x+=inc_xl;y+=inc_yl;d+=add_dl;} /* previous point was L type */ for(j=0;j (cur_z>>G_P)) /* Z buffer check */ { *adr_z=cur_z>>G_P; /* store new deapth here */ *adr_c=hwcolour; /* flat colour here */ } cur_z+=inc_z; /* next value for Z */ } #endif #if defined(_PAINTER_) HW_set_pixel(adr_c,span+1,hwcolour); /* drawing a strip */ #endif } } } /**********************************************************\ * Rendering an Interpolatively shaded polygon. * * Accepts a stream of three-tuples ( X Y Intensity ) * * for _CI_ and 5-tuples ( X Y R G B ) for _RGB_ * * similarely it is ( X Y Z etc. ) if _Z_BUFFER_ * \**********************************************************/ void G_shaded_polygon(int *edges,int length,HW_pixel colour) { int new_edges[G_MAX_POLYGON_VERTICES*G_LNG_SHADED]; int new_length,i; long pos; register HW_pixel *adr_c; register int beg,end,span; #if defined(_CI_) register HW_32_bit cur_i,inc_i; /* current colour */ #endif #if defined(_RGB_) register HW_32_bit cur_r,inc_r,cur_g,inc_g,cur_b,inc_b; #endif #if defined(_Z_BUFFER_) int *adr_z; /* position in the Z buffer */ register HW_32_bit cur_z,inc_z; /* current depth */ #endif GI_boarder_array_init(); /* initializing the array */ new_length=C_polygon_x_clipping(edges,new_edges,G_LNG_SHADED,length); for(i=0;i (cur_z>>G_P)) /* Z buffer check */ { *adr_z=cur_z>>G_P; /* store new deapth here */ #endif #if defined(_PAINTER_) for(;beg<=end;beg++,adr_c++) /* same, no Z check */ { { #endif #if defined(_CI_) *adr_c=CL_light(colour,cur_i>>G_P); /* rendering single point */ } cur_i+=inc_i; /* incrementing colour */ #endif #if defined(_RGB_) *adr_c=CL_light(colour,cur_r>>G_P,cur_g>>G_P,cur_b>>G_P); } cur_r+=inc_r; cur_g+=inc_g; cur_b+=inc_b; /* increment RGB */ #endif #if defined(_Z_BUFFER_) cur_z+=inc_z; /* increment Z */ #endif } } } } /**********************************************************\ * Rendering a leanerely textured polygon. * * The applied texture is a square colourmap with: * * * * log_texture_size=log texture_size * * 2 * * * * Accepts a stream of 5-tuples ( X Y Intensity Tx Ty) * * for _CI_ and 5-tuples ( X Y R G B Tx Ty) for _RGB_ * * similarely it is one more ( X Y Z etc. ) if _Z_BUFFER_ * \**********************************************************/ void G_lin_textured_polygon(int *edges,int length, HW_pixel *texture, int log_texture_size ) { int new_edges[G_MAX_POLYGON_VERTICES*G_LNG_TEXTURED]; int new_length,i; /* although no edges there yet */ long pos; register HW_pixel *adr_c; register int beg,end,span; register HW_32_bit cur_tx,inc_tx; /* current position inside */ register HW_32_bit cur_ty,inc_ty; /* the texture */ #if defined(_CI_) register HW_32_bit cur_i,inc_i; /* current colour and it's inc */ #endif #if defined(_RGB_) register HW_32_bit cur_r,inc_r,cur_g,inc_g,cur_b,inc_b; #endif #if defined(_Z_BUFFER_) int *adr_z; /* position in the Z buffer */ register HW_32_bit cur_z,inc_z; /* current deapth */ #endif HW_32_bit txtrmasc=(0x1<<(log_texture_size+G_P))-0x1; GI_boarder_array_init(); /* initializing the array */ new_length=C_polygon_x_clipping(edges,new_edges,G_LNG_TEXTURED,length); for(i=0;i (cur_z>>G_P)) /* Z buffer check */ { *adr_z=cur_z>>G_P; #endif #if defined(_PAINTER_) for(;beg<=end;beg++,adr_c++) /* render all lines: */ { cur_tx&=txtrmasc; cur_ty&=txtrmasc; /* wrap around */ { #endif #if defined(_CI_) *adr_c=CL_light(*(texture+((cur_ty>>G_P)< >G_P)), cur_i>>G_P ); cur_i+=inc_i; } #endif #if defined(_RGB_) *adr_c=CL_light(*(texture+((cur_ty>>G_P)< >G_P)), cur_r>>G_P,cur_g>>G_P,cur_b>>G_P ); cur_r+=inc_r; cur_g+=inc_g; cur_b+=inc_b; } #endif cur_tx+=inc_tx; cur_ty+=inc_ty; /* new position inside texture */ #if defined(_Z_BUFFER_) cur_z+=inc_z; #endif } } } } /**********************************************************\ * Rendering a perspectively textured polygon. * * The applied texture is a square colourmap with: * * * * log_texture_size=log texture_size * * 2 * * * * Accepts a stream of 5-tuples ( X Y Intensity Tx Ty) * * for _CI_ and 5-tuples ( X Y R G B Tx Ty) for _RGB_ * * similarely it is one more ( X Y Z etc. ) if _Z_BUFFER_ * * * * log_texture_scale allowing scaling the texture, i.e. * * mapping a larger texture onto a smaller polygon or * * smaller texture onto a larger polygon. * \**********************************************************/ void G_prp_textured_polygon(int *edges,int length, int *O,int *u,int *v, HW_pixel *texture, int log_texture_size, int log_texture_scale ) { int new_edges[G_MAX_POLYGON_VERTICES*G_LNG_TEXTURED]; int new_length,i; HW_32_bit Vx,Vy,Vz; HW_32_bit Ux,Uy,Uz; /* extracting vectors */ HW_32_bit x0,y0,z0; HW_32_bit ui,uj,uc; HW_32_bit vi,vj,vc; HW_32_bit zi,zj,zc; /* back to texture coeficients */ HW_32_bit v0,u0; HW_32_bit xx,yy,zz,zzz; long pos; HW_pixel *adr_c; register int beg,end,span; HW_32_bit cur_tx,inc_tx,end_tx,cur_ty,inc_ty,end_ty; #if defined(_CI_) register HW_32_bit cur_i,inc_i; /* current colour and it's inc */ #endif #if defined(_RGB_) register HW_32_bit cur_r,inc_r,cur_g,inc_g,cur_b,inc_b; #endif #if defined(_Z_BUFFER_) int *adr_z; /* position in the Z buffer */ register HW_32_bit cur_z,inc_z; /* current deapth */ #endif register int x,y; HW_32_bit txtrmasc=(0x1<<(log_texture_size+G_P))-0x1; GI_boarder_array_init(); /* initializing the array */ new_length=C_polygon_x_clipping(edges,new_edges,G_LNG_TEXTURED,length); for(i=0;i texture point */ Vx=v[0]; Vy=v[1]; Vz=v[2]; Ux=u[0]; Uy=u[1]; Uz=u[2]; /* extracting vectors */ ui=(Vz*y0)-(Vy*z0); uj=(Vx*z0)-(Vz*x0); uc=(Vy*x0)-(Vx*y0); vi=(Uy*z0)-(Uz*y0); vj=(Uz*x0)-(Ux*z0); vc=(Ux*y0)-(Uy*x0); zi=(Vy*Uz)-(Vz*Uy); zj=(Vz*Ux)-(Vx*Uz); zc=(Vx*Uy)-(Vy*Ux); /* back to texture coefs */ pos=G_miny*HW_SCREEN_LINE_SIZE+G_page_start; for(;G_miny >M_camera_log_focus)+uc; yy=((y*vj)>>M_camera_log_focus)+vc; zz=((y*zj)>>M_camera_log_focus)+zc; /* valid for the whole run */ if((zzz=zz+((x*zi)>>M_camera_log_focus))!=0) { end_tx=((((xx+((x*ui)>>M_camera_log_focus))< >M_camera_log_focus))< end) x=end; /* size of linear run */ cur_tx=end_tx; cur_ty=end_ty; if((zzz=zz+((x*zi)>>M_camera_log_focus))!=0) { end_tx=((((xx+((x*ui)>>M_camera_log_focus))< >M_camera_log_focus))< (cur_z>>G_P)) /* Z buffer check */ { *adr_z=cur_z>>G_P; #endif #if defined(_PAINTER_) for(;beg<=x;beg++,adr_c++) /* linear run */ { cur_tx&=txtrmasc; cur_ty&=txtrmasc; /* wrap around */ { #endif #if defined(_CI_) *adr_c=CL_light(*(texture+((cur_ty>>G_P)< >G_P)), cur_i>>G_P ); cur_i+=inc_i; } #endif #if defined(_RGB_) *adr_c=CL_light(*(texture+((cur_ty>>G_P)< >G_P)), cur_r>>G_P,cur_g>>G_P,cur_b>>G_P ); cur_r+=inc_r; cur_g+=inc_g; cur_b+=inc_b; } #endif cur_tx+=inc_tx; cur_ty+=inc_ty; /* new position in the texture */ #if defined(_Z_BUFFER_) cur_z+=inc_z; #endif } } } } } /**********************************************************/