#help_index "Graphics" public I64 GrFillPoly3(CDC *dc=gr.dc, I64 n, CD3I32 *poly) {//3D. Must be convex. //Returns count of pixs changed CD3I32 tri[3]; I64 i, j, x, y, z, res = 0; if (n < 3) return 0; if (dc->flags & DCF_SYMMETRY) { for (i = 1; i < n - 1; i++) { j = i - 1; if (i == 1) { x = poly[j].x; y = poly[j].y; z = poly[j].z; if (dc->flags & DCF_TRANSFORMATION) (*dc->transform)(dc, &x, &y, &z); DCReflect(dc, &x, &y, &z); tri[0].x = x; tri[0].y = y; tri[0].z = z; } j++; if (i == 1) { x = poly[j].x; y = poly[j].y; z = poly[j].z; if (dc->flags & DCF_TRANSFORMATION) (*dc->transform)(dc, &x, &y, &z); DCReflect(dc, &x, &y, &z); } tri[1].x = x; tri[1].y = y; tri[1].z = z; j++; x = poly[j].x; y = poly[j].y; z = poly[j].z; if (dc->flags & DCF_TRANSFORMATION) (*dc->transform)(dc, &x, &y, &z); DCReflect(dc, &x, &y, &z); tri[2].x = x; tri[2].y = y; tri[2].z = z; res += GrFillTri0(dc, &tri[0], &tri[1], &tri[2]); } } if (dc->flags & DCF_JUST_MIRROR) return res; for (i = 1; i < n - 1; i++) { j = i - 1; if (i == 1) { x = poly[j].x; y = poly[j].y; z = poly[j].z; if (dc->flags & DCF_TRANSFORMATION) (*dc->transform)(dc, &x, &y, &z); tri[0].x = x; tri[0].y = y; tri[0].z = z; } j++; if (i == 1) { x = poly[j].x; y = poly[j].y; z = poly[j].z; if (dc->flags & DCF_TRANSFORMATION) (*dc->transform)(dc, &x, &y, &z); } tri[1].x = x; tri[1].y = y; tri[1].z = z; j++; x = poly[j].x; y = poly[j].y; z = poly[j].z; if (dc->flags & DCF_TRANSFORMATION) (*dc->transform)(dc, &x, &y, &z); tri[2].x = x; tri[2].y = y; tri[2].z = z; res += GrFillTri0(dc, &tri[0], &tri[1], &tri[2]); } return res; } public I64 GrRectB(CDC *dc=gr.dc, I64 x1, I64 y1, I64 x2, I64 y2) {//2D. Two point. Clipping but not transformation. if (x2 < x1) SwapI64(&x1, &x2); if (y2 < y1) SwapI64(&y1, &y2); return GrRect(dc, x1, y1, x2 - x1 + 1, y2 - y1 + 1); } public I64 GrRect3(CDC *dc=gr.dc, I64 x, I64 y, I64 z, I64 w, I64 h) {//3D. Width Height. Clipping and transformation. CD3I32 poly[4]; poly[0].x = x; poly[0].y = y; poly[0].z = z; poly[1].x = x + w; poly[1].y = y; poly[1].z = z; poly[2].x = x + w; poly[2].y = y + h; poly[2].z = z; poly[3].x = x; poly[3].y = y + h; poly[3].z = z; return GrFillPoly3(dc, 4, poly); } public U0 GrBorder(CDC *dc=gr.dc, I64 x1, I64 y1, I64 x2, I64 y2, I64 step=1, I64 start=0) {//2D. Transformation with thick. //Can be used with ROPF_DITHER+WHITE<<16+BLACK for dotted rect. GrLine3(dc, x1, y1, 0, x2, y1, 0, step, start); GrLine3(dc, x2, y1, 0, x2, y2, 0, step, start); GrLine3(dc, x2, y2, 0, x1, y2, 0, step, start); GrLine3(dc, x1, y2, 0, x1, y1, 0, step, start); } public Bool GrArrow3(CDC *dc=gr.dc, I64 x1, I64 y1, I64 z1, I64 x2, I64 y2, I64 z2, F64 w=2.75, I64 step=1, I64 start=0) {//3D. Transformation with thick. I64 _x1, _y1, _z1, _x2, _y2, _z2, dx, dy; F64 d; Bool res = FALSE, was_transform = FALSE, was_symmetry = FALSE; if (dc->flags & DCF_TRANSFORMATION) { (*dc->transform)(dc, &x1, &y1, &z1); (*dc->transform)(dc, &x2, &y2, &z2); dc->flags &= ~DCF_TRANSFORMATION; was_transform = TRUE; } if (dc->flags & DCF_SYMMETRY) { _x1 = x1; _y1 = y1; _z1 = z1; DCReflect(dc, &_x1, &_y1, &_z1); _x2 = x2; _y2 = y2; _z2 = z2; DCReflect(dc, &_x2, &_y2, &_z2); dc->flags &= ~DCF_SYMMETRY; res=Line(dc, _x1, _y1, _z1, _x2, _y2, _z2, &GrPlot3, step, start); dx = _x2 - _x1; dy = _y2 - _y1; if (d = Sqrt(dx * dx + dy * dy)) { d = w * dc->thick / d; res |= Line(dc, _x2 - dx * d + dy * d + 0.5, _y2 - dy * d - dx * d + 0.5, _z2, _x2, _y2, _z2, &GrPlot3, step); res |= Line(dc, _x2 - dx * d - dy * d + 0.5, _y2 - dy * d + dx * d + 0.5, _z2, _x2, _y2, _z2, &GrPlot3, step); } was_symmetry = TRUE; if (dc->flags & DCF_JUST_MIRROR) goto gr_done; } res |= Line(dc, x1, y1, z1, x2, y2, z2, &GrPlot3, step, start); dx = x2 - x1; dy = y2 - y1; if (d = Sqrt(dx * dx + dy * dy)) { d = w * dc->thick / d; res |= Line(dc, x2 - dx * d + dy * d + 0.5, y2 - dy * d - dx * d + 0.5, z2, x2, y2, z2, &GrPlot3, step); res |= Line(dc, x2 - dx * d - dy * d + 0.5, y2 - dy * d + dx * d + 0.5, z2, x2, y2, z2, &GrPlot3, step); } gr_done: if (was_transform) dc->flags |= DCF_TRANSFORMATION; if (was_symmetry) dc->flags |= DCF_SYMMETRY; return res; } #help_index "Graphics/Char;Char/Graphics" public Bool GrTextBox3(CDC *dc=gr.dc, I64 x1, I64 y1, I64 z1, U8 *s, I64 border=2) {//3D. Transformation. DCF_SYMMETRY is silly. U8 *ptr; I64 ch, res, w, w_max, h; if (!s) return FALSE; ptr = s; w = 0; w_max = 0; h = FONT_HEIGHT; if (dc->flags & DCF_TRANSFORMATION) (*dc->transform)(dc, &x1, &y1, &z1); while (ch = *ptr++) { if (ch == '\t') w = CeilU64(w + FONT_WIDTH, FONT_WIDTH * 8); else if (ch == '\n') { if (w > w_max) w_max = w; w = 0; h += FONT_HEIGHT; } else w += FONT_WIDTH; } if (w > w_max) w_max = w; res = GrPrint(dc, x1, y1, "%s", s); res |= GrLine(dc, x1 - border, y1 - border, x1 + w_max + border, y1 - border); res |= GrLine(dc, x1 - border, y1 + h + border, x1 + w_max + border, y1 + h + border); res |= GrLine(dc, x1 - border, y1 - border, x1 - border, y1 + h + border); res |= GrLine(dc, x1 + w_max + border, y1 - border, x1 + w_max + border, y1 + h + border); return ToBool(res); } #define DIAMOND_SLOPE_MAX 2.75 public Bool GrTextDiamond3(CDC *dc=gr.dc, I64 x1, I64 y1, I64 z1, U8 *_s, I64 border=2) {//3D. Transformation. DCF_SYMMETRY is silly. Bool first = TRUE; U8 ch, *ptr, *ptr_end, *st, *s; I64 res = 0, y, dx, dy, dx_old, dy_old, w, h = FONT_HEIGHT; F64 m; if (!_s) return FALSE; if (dc->flags & DCF_TRANSFORMATION) (*dc->transform)(dc, &x1, &y1, &z1); ptr = s = StrNew(_s); while (ch = *ptr) { if (ch == '\r'||ch == '\t') *ptr = CH_SPACE; if (ch == '\n') { *ptr = 0; h += FONT_HEIGHT; } ptr++; } ptr_end = ptr + 1; y = y1 - h >> 1; dx = FONT_WIDTH + border; //Minimum dy = FONT_HEIGHT + border + h >> 1; //Minimum ptr = s; while (ptr != ptr_end) { st = ptr; while (*ptr++); StrUtil(st, SUF_REM_LEADING | SUF_REM_TRAILING); w = (StrLen(st) * FONT_WIDTH) >> 1; if (first) { res |= GrPrint(dc, x1 - w, y, "%s", st); first = FALSE; } else res |= GrPrint(dc, x1 - w, y, "%s", st); if (w) { w += border; do { dx_old = dx; dy_old = dy; m = ToF64(dx) / dy; if (m < 1 / DIAMOND_SLOPE_MAX) { dy = MaxI64(dy, Ceil(DIAMOND_SLOPE_MAX * dx)); m = 1 / DIAMOND_SLOPE_MAX; } else if (m > DIAMOND_SLOPE_MAX) { dy = MaxI64(dy, Ceil(dx / DIAMOND_SLOPE_MAX)); m = DIAMOND_SLOPE_MAX; } dx = MaxI64(dx, w + Ceil(m * AbsI64(y - y1))); dx = MaxI64(dx, w + Ceil(m * AbsI64(y + FONT_HEIGHT - y1))); } while (dx != dx_old || dy != dy_old); } y += FONT_HEIGHT; } Free(s); res |= GrLine(dc, x1, y1 - dy, x1 + dx, y1); res |= GrLine(dc, x1 + dx, y1, x1, y1 + dy); res |= GrLine(dc, x1, y1 + dy, x1 - dx, y1); res |= GrLine(dc, x1 - dx, y1, x1, y1 - dy); return ToBool(res); } #help_index "Graphics/Mesh" public I64 Gr3Mesh(CDC *dc=gr.dc, I64 vertex_count, CD3I32 *p, I64 tri_count, CMeshTri *tri) {//Returns count of pixs changed. CColorROPU32 old_color = dc->color; I64 i, x, y, z, res = 0; CD3I32 *pt, *pt_sym, *p_sym, *dst; CMeshTri *tri_sym = tri; if (dc->flags & DCF_TRANSFORMATION) { dst = pt = MAlloc(sizeof(CD3I32) * vertex_count); for (i = 0; i < vertex_count; i++, p++, dst++) { x = p->x; y = p->y; z = p->z; (*dc->transform)(dc, &x, &y, &z); dst->x = x; dst->y = y; dst->z = z; } p = pt; } else pt = NULL; if (dc->flags & DCF_SYMMETRY) { dst = pt_sym = MAlloc(sizeof(CD3I32) * vertex_count); p_sym = p; for (i = 0; i < vertex_count; i++, p_sym++, dst++) { x = p_sym->x; y = p_sym->y; z = p_sym->z; DCReflect(dc, &x, &y, &z); dst->x = x; dst->y = y; dst->z = z; } p_sym = pt_sym; for (i = 0; i < tri_count; i++, tri_sym++) { (*dc->lighting)(dc, &p_sym[tri_sym->nums[0]], &p_sym[tri_sym->nums[2]], &p_sym[tri_sym->nums[1]], tri_sym->color); res += GrFillTri0(dc, &p_sym[tri_sym->nums[0]], &p_sym[tri_sym->nums[2]], &p_sym[tri_sym->nums[1]]); } Free(pt_sym); if (dc->flags & DCF_JUST_MIRROR) goto mesh_done; } for (i = 0; i < tri_count; i++, tri++) { (*dc->lighting)(dc, &p[tri->nums[0]], &p[tri->nums[1]], &p[tri->nums[2]], tri->color); res += GrFillTri0(dc, &p[tri->nums[0]], &p[tri->nums[1]], &p[tri->nums[2]]); } mesh_done: dc->color = old_color; Free(pt); return res; } public U0 DrawWaitMouse(CDC *dc, I64 x, I64 y) {//This is a callback. See ::/Demo/Graphics/Grid.ZC. I64 old_pen_width = dc->thick; CColorROPU32 old_color = dc->color; dc->thick = 3; dc->color = LTRED; GrCircle3(dc, x, y, 0, 7); GrLine3(dc, x - 6, y + 6, 0, x + 6, y - 6, 0); dc->color = RED; GrCircle(dc, x, y, 7); GrLine(dc, x - 6, y + 6, x + 6, y - 6); dc->thick = old_pen_width; dc->color = old_color; } #help_index "Graphics/GR Files;Graphics/Screen" public Bool GRScreenCaptureRead(U8 *filename, CDC *dc=gr.dc, I64 x=0, I64 y=0) {//GrBlot ZealOS GR File to dc, x, y. CDC *dc2; if (dc2 = GRRead(filename)) { dc->color = ROP_EQU; GrBlot(dc, x, y, dc2); DCDel(dc2); return TRUE; } return FALSE; } public I64 GRScreenCaptureWrite(U8 *filename, Bool include_zoom=TRUE) {//Capture screen to a ZealOS GR File. I64 size; CDC *dc = DCScreenCapture(include_zoom); size = GRWrite(filename, dc, DCSF_PALETTE_GET); DCDel(dc); return size; }