//draws a line. takes two points. returns true if drew bool g3_draw_line(g3s_point *p0,g3s_point *p1) { ubyte codes_or; if (p0->p3_codes & p1->p3_codes) return 0; codes_or = p0->p3_codes | p1->p3_codes; if (codes_or & CC_BEHIND) return must_clip_line(p0,p1,codes_or); if (!(p0->p3_flags&PF_PROJECTED)) g3_project_point(p0); if (p0->p3_flags&PF_OVERFLOW) return must_clip_line(p0,p1,codes_or); if (!(p1->p3_flags&PF_PROJECTED)) g3_project_point(p1); if (p1->p3_flags&PF_OVERFLOW) return must_clip_line(p0,p1,codes_or); return (bool) (*line_drawer_ptr)(p0->p3_sx,p0->p3_sy,p1->p3_sx,p1->p3_sy); }
//draws a bitmap with the specified 3d width & height //returns 1 if off screen, 0 if drew void g3_draw_bitmap(const vms_vector &pos,fix width,fix height,grs_bitmap &bm) { g3s_point pnt; fix w,h; if (g3_rotate_point(pnt,pos) & CC_BEHIND) return; g3_project_point(pnt); if (pnt.p3_flags & PF_OVERFLOW) return; #ifndef __powerc fix t; if (checkmuldiv(&t,width,Canv_w2,pnt.p3_z)) w = fixmul(t,Matrix_scale.x); else return; if (checkmuldiv(&t,height,Canv_h2,pnt.p3_z)) h = fixmul(t,Matrix_scale.y); else return; #else if (pnt.p3_z == 0) return; double fz = f2fl(pnt.p3_z); w = fixmul(fl2f(((f2fl(width)*fCanv_w2) / fz)), Matrix_scale.x); h = fixmul(fl2f(((f2fl(height)*fCanv_h2) / fz)), Matrix_scale.y); #endif const fix blob0y = pnt.p3_sy - h, blob1x = pnt.p3_sx + w; const array<grs_point, 3> blob_vertices{{ {pnt.p3_sx - w, blob0y}, {blob1x, blob0y}, {blob1x, pnt.p3_sy + h}, }}; scale_bitmap(bm, blob_vertices, 0); }
void draw_stars() { int i; int intensity=31; g3s_point p; for (i=0;i<MAX_STARS;i++) { if ((i&63) == 0) { gr_setcolor(BM_XRGB(intensity,intensity,intensity)); intensity-=3; } //g3_rotate_point(&p,&stars[i]); g3_rotate_delta_vec(&p.p3_vec,&stars[i]); g3_code_point(&p); if (p.p3_codes == 0) { p.p3_flags &= ~PF_PROJECTED; g3_project_point(&p); #ifndef OGL gr_pixel(f2i(p.p3_sx),f2i(p.p3_sy)); #else g3_draw_sphere(&p,F1_0*3); #endif } } //@@ { //@@ vms_vector delta; //@@ g3s_point top_pnt; //@@ //@@ g3_rotate_point(&p,&satellite_pos); //@@ g3_rotate_delta_vec(&delta,&satellite_upvec); //@@ //@@ g3_add_delta_vec(&top_pnt,&p,&delta); //@@ //@@ if (! (p.p3_codes & CC_BEHIND)) { //@@ int save_im = Interpolation_method; //@@ Interpolation_method = 0; //@@ //p.p3_flags &= ~PF_PROJECTED; //@@ g3_project_point(&p); //@@ if (! (p.p3_flags & PF_OVERFLOW)) //@@ //gr_bitmapm(f2i(p.p3_sx)-32,f2i(p.p3_sy)-32,satellite_bitmap); //@@ g3_draw_rod_tmap(satellite_bitmap,&p,SATELLITE_WIDTH,&top_pnt,SATELLITE_WIDTH,f1_0); //@@ Interpolation_method = save_im; //@@ } //@@ } }
//draw a texture-mapped face. //returns 1 if off screen, 0 if drew bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,g3s_lrgb *light_rgb,grs_bitmap *bm) { int i; g3s_point **bufptr; g3s_codes cc; cc.uor = 0; cc.uand = 0xff; bufptr = Vbuf0; for (i=0;i<nv;i++) { g3s_point *p; p = bufptr[i] = pointlist[i]; cc.uand &= p->p3_codes; cc.uor |= p->p3_codes; p->p3_u = uvl_list[i].u; p->p3_v = uvl_list[i].v; p->p3_l = (light_rgb[i].r+light_rgb[i].g+light_rgb[i].b)/3; p->p3_flags |= PF_UVS + PF_LS; } if (cc.uand) return 1; //all points off screen if (cc.uor) return must_clip_tmap_face(nv,cc,bm); //now make list of 2d coords (& check for overflow) for (i=0;i<nv;i++) { g3s_point *p = bufptr[i]; if (!(p->p3_flags&PF_PROJECTED)) g3_project_point(p); if (p->p3_flags&PF_OVERFLOW) { Int3(); //should not overflow after clip return 255; } } (*tmap_drawer_ptr)(bm,nv,bufptr); return 0; //say it drew }
//draw a flat-shaded face. //returns 1 if off screen, 0 if drew bool g3_draw_poly(int nv,g3s_point **pointlist) { int i; g3s_point **bufptr; g3s_codes cc; cc.uor = 0; cc.uand = 0xff; bufptr = Vbuf0; for (i=0;i<nv;i++) { bufptr[i] = pointlist[i]; cc.uand &= bufptr[i]->p3_codes; cc.uor |= bufptr[i]->p3_codes; } if (cc.uand) return 1; //all points off screen if (cc.uor) return must_clip_flat_face(nv,cc); //now make list of 2d coords (& check for overflow) for (i=0;i<nv;i++) { g3s_point *p = bufptr[i]; if (!(p->p3_flags&PF_PROJECTED)) g3_project_point(p); if (p->p3_flags&PF_OVERFLOW) return must_clip_flat_face(nv,cc); Vertex_list[i*2] = p->p3_sx; Vertex_list[i*2+1] = p->p3_sy; } (*flat_drawer_ptr)(nv,(int *)Vertex_list); return 0; //say it drew }
//deal with face that must be clipped bool must_clip_flat_face(int nv,g3s_codes cc) { int i; bool ret=0; g3s_point **bufptr; bufptr = clip_polygon(Vbuf0,Vbuf1,&nv,&cc); if (nv>0 && !(cc.uor&CC_BEHIND) && !cc.uand) { for (i=0;i<nv;i++) { g3s_point *p = bufptr[i]; if (!(p->p3_flags&PF_PROJECTED)) g3_project_point(p); if (p->p3_flags&PF_OVERFLOW) { ret = 1; goto free_points; } Vertex_list[i*2] = p->p3_sx; Vertex_list[i*2+1] = p->p3_sy; } (*flat_drawer_ptr)(nv,(int *)Vertex_list); } else ret=1; //free temp points free_points: ; for (i=0;i<nv;i++) if (Vbuf1[i]->p3_flags & PF_TEMP_POINT) free_temp_point(Vbuf1[i]); // Assert(free_point_num==0); return ret; }
//draw a sortof sphere - i.e., the 2d radius is proportional to the 3d //radius, but not to the distance from the eye int g3_draw_sphere(g3s_point *pnt,fix rad) { if (! (pnt->p3_codes & CC_BEHIND)) { if (! (pnt->p3_flags & PF_PROJECTED)) g3_project_point(pnt); if (! (pnt->p3_codes & PF_OVERFLOW)) { fix r2,t; r2 = fixmul(rad,Matrix_scale.x); #ifndef __powerc if (checkmuldiv(&t,r2,Canv_w2,pnt->p3_z)) return gr_disk(pnt->p3_sx,pnt->p3_sy,t); #else if (pnt->p3_z == 0) return 0; return gr_disk(pnt->p3_sx, pnt->p3_sy, fl2f(((f2fl(r2) * fCanv_w2) / f2fl(pnt->p3_z)))); #endif } } return 0; }
bool must_clip_tmap_face(int nv,g3s_codes cc,grs_bitmap *bm) { g3s_point **bufptr; int i; bufptr = clip_polygon(Vbuf0,Vbuf1,&nv,&cc); if (nv && !(cc.uor&CC_BEHIND) && !cc.uand) { for (i=0;i<nv;i++) { g3s_point *p = bufptr[i]; if (!(p->p3_flags&PF_PROJECTED)) g3_project_point(p); if (p->p3_flags&PF_OVERFLOW) { Int3(); //should not overflow after clip goto free_points; } } (*tmap_drawer_ptr)(bm,nv,bufptr); } free_points: ; for (i=0;i<nv;i++) if (bufptr[i]->p3_flags & PF_TEMP_POINT) free_temp_point(bufptr[i]); // Assert(free_point_num==0); return 0; }
void DrawMarkerNumber (automap *am, int num) { int i; g3s_point BasePoint,FromPoint,ToPoint; float ArrayX[10][20]={ {-.25, 0.0, 0.0, 0.0, -1.0, 1.0}, {-1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0}, {-1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 1.0}, {-1.0, -1.0, -1.0, 1.0, 1.0, 1.0}, {-1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0}, {-1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0}, {-1.0, 1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0}, {-1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0} }; float ArrayY[10][20]={ {.75, 1.0, 1.0, -1.0, -1.0, -1.0}, {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0}, {1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 0.0, 0.0}, {1.0, 0.0, 0.0, 0.0, 1.0, -1.0}, {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0}, {1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0}, {1.0, 1.0, 1.0, -1.0}, {1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 0.0, 0.0}, {1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0} }; int NumOfPoints[]={6,10,8,6,10,10,4,10,8}; for (i=0;i<NumOfPoints[num];i++) { ArrayX[num][i]*=MarkerScale; ArrayY[num][i]*=MarkerScale; } if (num==HighlightMarker) gr_setcolor (am->white_63); else gr_setcolor (am->blue_48); g3_rotate_point(&BasePoint,&Objects[MarkerObject[(Player_num*2)+num]].pos); for (i=0;i<NumOfPoints[num];i+=2) { FromPoint=BasePoint; ToPoint=BasePoint; FromPoint.p3_x+=fixmul ((fl2f (ArrayX[num][i])),Matrix_scale.x); FromPoint.p3_y+=fixmul ((fl2f (ArrayY[num][i])),Matrix_scale.y); g3_code_point (&FromPoint); g3_project_point (&FromPoint); ToPoint.p3_x+=fixmul ((fl2f (ArrayX[num][i+1])),Matrix_scale.x); ToPoint.p3_y+=fixmul ((fl2f (ArrayY[num][i+1])),Matrix_scale.y); g3_code_point (&ToPoint); g3_project_point (&ToPoint); automap_draw_line(&FromPoint, &ToPoint); } }
//draws a bitmap with the specified 3d width & height //returns 1 if off screen, 0 if drew bool g3_draw_bitmap(vms_vector *pos,fix width,fix height,grs_bitmap *bm) { #ifndef __powerc g3s_point pnt; fix t,w,h; if (g3_rotate_point(&pnt,pos) & CC_BEHIND) return 1; g3_project_point(&pnt); if (pnt.p3_flags & PF_OVERFLOW) return 1; if (checkmuldiv(&t,width,Canv_w2,pnt.p3_z)) w = fixmul(t,Matrix_scale.x); else return 1; if (checkmuldiv(&t,height,Canv_h2,pnt.p3_z)) h = fixmul(t,Matrix_scale.y); else return 1; blob_vertices[0].x = pnt.p3_sx - w; blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h; blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w; blob_vertices[2].y = pnt.p3_sy + h; scale_bitmap(bm,blob_vertices,0); return 0; #else g3s_point pnt; fix w,h; double fz; if (g3_rotate_point(&pnt,pos) & CC_BEHIND) return 1; g3_project_point(&pnt); if (pnt.p3_flags & PF_OVERFLOW) return 1; if (pnt.p3_z == 0) return 1; fz = f2fl(pnt.p3_z); w = fixmul(fl2f(((f2fl(width)*fCanv_w2) / fz)), Matrix_scale.x); h = fixmul(fl2f(((f2fl(height)*fCanv_h2) / fz)), Matrix_scale.y); blob_vertices[0].x = pnt.p3_sx - w; blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h; blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w; blob_vertices[2].y = pnt.p3_sy + h; scale_bitmap(bm, blob_vertices, 0); return 0; #endif }