void ExtObject::RenderDistorted() { // Enable tiling for distort maps. cr::samplerstate_value old_addressu = renderer->GetSamplerState(cr::ss_addressu); cr::samplerstate_value old_addressv = renderer->GetSamplerState(cr::ss_addressv); renderer->SetSamplerState(cr::ss_addressu, cr::ssv_wrap); renderer->SetSamplerState(cr::ss_addressv, cr::ssv_wrap); const point hotspot(info.HotSpotX, info.HotSpotY); rect rc(cr::rect_xywh(info.x, info.y, info.w, info.h)); quad q; if (info.angle == 0.0) q = quad(rc - hotspot); else q = (rc - hotspot).rotate_to_quad(cr::to_radians(info.angle), hotspot); rect unrotated_box(rc - hotspot); int cx = distort.size(); int cy = distort.front().size(); UINT vertex_count = cx * cy; UINT index_count = (cx - 1) * (cy - 1) * 6; renderer->BeginBatchQuads(vertex_count, index_count); for (int y = 0; y < cy - 1; y++) { for (int x = 0; x < cx - 1; x++) { // Add six indices for this quad renderer->AddIndex(x + y * cx); renderer->AddIndex((x+1) + y * cx); renderer->AddIndex(x + (y+1) * cx); renderer->AddIndex(x + (y+1) * cx); renderer->AddIndex((x+1) + y * cx); renderer->AddIndex((x+1) + (y+1) * cx); } } float xsize = cx; float ysize = cy; point tex_scale(info.curTexture->xf, info.curTexture->yf); point object_scale_factor(info.w / info.curTexture->image_widthf, info.h / info.curTexture->image_heightf); float average_scale_factor = (object_scale_factor.x + object_scale_factor.y) / 2.0f; for (int y = 0; y < cy; y++) { for (int x = 0; x < cx; x++) { const DistortInfo& di = distort[x][y]; point current_ratio((float)x / (xsize - 1.0f), (float)y / (ysize - 1.0f)); point p(lerp2D(unrotated_box.topleft(), unrotated_box.bottomright(), current_ratio)); p += point(di.x * info.w, di.y * info.h) * object_scale_factor; // xy offset if (info.angle != 0.0) p.rotate(cr::to_radians(info.angle), info.x, info.y); cr::point3d final_pt(p.x, p.y, (di.z + info.pInfo->z_elevation) * average_scale_factor); point uv_offset(di.u, di.v); point uv(current_ratio + uv_offset); renderer->AddVertex(final_pt, uv * tex_scale, di.filter * info.pInfo->filter); } } // Restore previous wrap mode renderer->SetSamplerState(cr::ss_addressu, old_addressu); renderer->SetSamplerState(cr::ss_addressv, old_addressv); }
scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform) { /*tex size and resolution of image */ int x, y, xr, yr, tmp; /*tex natural size corresponding to image resolution */ scaled_whd nat; int default_res; nat.dp = 0; nat.wd = 0; nat.ht = 0; if (img_nobbox(idict)) { if (img_is_bbox(idict)) { x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1]; img_xorig(idict) = img_bbox(idict)[0]; img_yorig(idict) = img_bbox(idict)[1]; nat.wd = x; nat.ht = y; } else { normal_error("pdf backend","use boundingbox to pass dimensions"); } } else { if ((img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM || img_type(idict) == IMG_TYPE_PDFSTREAM) && img_is_bbox(idict)) { /*tex dimensions from image.bbox */ x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1]; img_xorig(idict) = img_bbox(idict)[0]; img_yorig(idict) = img_bbox(idict)[1]; } else { /*tex dimensions, resolutions from image file */ x = img_xsize(idict); y = img_ysize(idict); } xr = img_xres(idict); yr = img_yres(idict); if (x <= 0 || y <= 0 || xr < 0 || yr < 0) normal_error("pdf backend","invalid image dimensions"); if (xr > 65535 || yr > 65535) { xr = 0; yr = 0; normal_warning("pdf backend","too large image resolution ignored"); } if (((transform - img_rotation(idict)) & 1) == 1) { tmp = x; x = y; y = tmp; tmp = xr; xr = yr; yr = tmp; } /*tex always for images */ if (img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM || img_type(idict) == IMG_TYPE_PDFSTREAM) { nat.wd = x; nat.ht = y; } else { default_res = fix_int(pdf_image_resolution, 0, 65535); if (default_res > 0 && (xr == 0 || yr == 0)) { xr = default_res; yr = default_res; } if (xr > 0 && yr > 0) { nat.wd = ext_xn_over_d(one_hundred_inch, x, 100 * xr); nat.ht = ext_xn_over_d(one_hundred_inch, y, 100 * yr); } else { nat.wd = ext_xn_over_d(one_hundred_inch, x, 7200); nat.ht = ext_xn_over_d(one_hundred_inch, y, 7200); } } } return tex_scale(nat, alt_rule); }
inline void SpatialSceneBuilder::tex_scale(double f) { tex_scale(f,f); }