|
Blender
V2.59
|
00001 /* 00002 * $Id: image_draw.c 36715 2011-05-16 13:34:42Z blendix $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): Blender Foundation, 2002-2009 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <math.h> 00034 #include <stdlib.h> 00035 #include <string.h> 00036 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "DNA_camera_types.h" 00040 #include "DNA_object_types.h" 00041 #include "DNA_space_types.h" 00042 #include "DNA_scene_types.h" 00043 #include "DNA_screen_types.h" 00044 #include "DNA_brush_types.h" 00045 00046 #include "PIL_time.h" 00047 00048 #include "BLI_math.h" 00049 #include "BLI_threads.h" 00050 #include "BLI_string.h" 00051 #include "BLI_utildefines.h" 00052 00053 #include "IMB_imbuf.h" 00054 #include "IMB_imbuf_types.h" 00055 00056 #include "BKE_context.h" 00057 #include "BKE_global.h" 00058 #include "BKE_image.h" 00059 #include "BKE_paint.h" 00060 00061 #include "BIF_gl.h" 00062 #include "BIF_glutil.h" 00063 00064 #include "BLF_api.h" 00065 00066 #include "ED_gpencil.h" 00067 #include "ED_image.h" 00068 00069 #include "UI_interface.h" 00070 #include "UI_resources.h" 00071 #include "UI_view2d.h" 00072 00073 00074 #include "RE_pipeline.h" 00075 00076 #include "image_intern.h" 00077 00078 #define HEADER_HEIGHT 18 00079 00080 static void image_verify_buffer_float(Image *ima, ImBuf *ibuf, int color_manage) 00081 { 00082 /* detect if we need to redo the curve map. 00083 ibuf->rect is zero for compositor and render results after change 00084 convert to 32 bits always... drawing float rects isnt supported well (atis) 00085 00086 NOTE: if float buffer changes, we have to manually remove the rect 00087 */ 00088 00089 if(ibuf->rect_float && (ibuf->rect==NULL || (ibuf->userflags & IB_RECT_INVALID)) ) { 00090 if(color_manage) { 00091 if(ima && ima->source == IMA_SRC_VIEWER) 00092 ibuf->profile = IB_PROFILE_LINEAR_RGB; 00093 } 00094 else 00095 ibuf->profile = IB_PROFILE_NONE; 00096 00097 IMB_rect_from_float(ibuf); 00098 } 00099 } 00100 00101 static void draw_render_info(Scene *scene, Image *ima, ARegion *ar) 00102 { 00103 RenderResult *rr; 00104 rcti rect; 00105 float colf[3]; 00106 00107 rr= BKE_image_acquire_renderresult(scene, ima); 00108 00109 if(rr && rr->text) { 00110 rect= ar->winrct; 00111 rect.xmin= 0; 00112 rect.ymin= ar->winrct.ymax - ar->winrct.ymin - HEADER_HEIGHT; 00113 rect.xmax= ar->winrct.xmax - ar->winrct.xmin; 00114 rect.ymax= ar->winrct.ymax - ar->winrct.ymin; 00115 00116 /* clear header rect */ 00117 UI_GetThemeColor3fv(TH_BACK, colf); 00118 glEnable(GL_BLEND); 00119 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 00120 glColor4f(colf[0]+0.1f, colf[1]+0.1f, colf[2]+0.1f, 0.5f); 00121 glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax+1); 00122 glDisable(GL_BLEND); 00123 00124 UI_ThemeColor(TH_TEXT_HI); 00125 00126 UI_DrawString(12, rect.ymin + 5, rr->text); 00127 } 00128 00129 BKE_image_release_renderresult(scene, ima); 00130 } 00131 00132 void draw_image_info(ARegion *ar, int color_manage, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf) 00133 { 00134 char str[256]; 00135 float dx= 6; 00136 /* text colors */ 00137 /* XXX colored text not allowed in Blender UI */ 00138 #if 0 00139 unsigned char red[3] = {255, 50, 50}; 00140 unsigned char green[3] = {0, 255, 0}; 00141 unsigned char blue[3] = {100, 100, 255}; 00142 #else 00143 unsigned char red[3] = {255, 255, 255}; 00144 unsigned char green[3] = {255, 255, 255}; 00145 unsigned char blue[3] = {255, 255, 255}; 00146 #endif 00147 float hue=0, sat=0, val=0, lum=0, u=0, v=0; 00148 float col[4], finalcol[4]; 00149 00150 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 00151 glEnable(GL_BLEND); 00152 00153 /* noisy, high contrast make impossible to read if lower alpha is used. */ 00154 glColor4ub(0, 0, 0, 190); 00155 glRecti(0.0, 0.0, ar->winrct.xmax - ar->winrct.xmin + 1, 20); 00156 glDisable(GL_BLEND); 00157 00158 BLF_size(blf_mono_font, 11, 72); 00159 00160 glColor3ub(255, 255, 255); 00161 sprintf(str, "X:%-4d Y:%-4d |", x, y); 00162 // UI_DrawString(6, 6, str); // works ok but fixed width is nicer. 00163 BLF_position(blf_mono_font, dx, 6, 0); 00164 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00165 dx += BLF_width(blf_mono_font, str); 00166 00167 if(zp) { 00168 glColor3ub(255, 255, 255); 00169 sprintf(str, " Z:%-.4f |", 0.5f+0.5f*(((float)*zp)/(float)0x7fffffff)); 00170 BLF_position(blf_mono_font, dx, 6, 0); 00171 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00172 dx += BLF_width(blf_mono_font, str); 00173 } 00174 if(zpf) { 00175 glColor3ub(255, 255, 255); 00176 sprintf(str, " Z:%-.3f |", *zpf); 00177 BLF_position(blf_mono_font, dx, 6, 0); 00178 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00179 dx += BLF_width(blf_mono_font, str); 00180 } 00181 00182 if(channels >= 3) { 00183 glColor3ubv(red); 00184 if (fp) 00185 sprintf(str, " R:%-.4f", fp[0]); 00186 else if (cp) 00187 sprintf(str, " R:%-3d", cp[0]); 00188 else 00189 sprintf(str, " R:-"); 00190 BLF_position(blf_mono_font, dx, 6, 0); 00191 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00192 dx += BLF_width(blf_mono_font, str); 00193 00194 glColor3ubv(green); 00195 if (fp) 00196 sprintf(str, " G:%-.4f", fp[1]); 00197 else if (cp) 00198 sprintf(str, " G:%-3d", cp[1]); 00199 else 00200 sprintf(str, " G:-"); 00201 BLF_position(blf_mono_font, dx, 6, 0); 00202 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00203 dx += BLF_width(blf_mono_font, str); 00204 00205 glColor3ubv(blue); 00206 if (fp) 00207 sprintf(str, " B:%-.4f", fp[2]); 00208 else if (cp) 00209 sprintf(str, " B:%-3d", cp[2]); 00210 else 00211 sprintf(str, " B:-"); 00212 BLF_position(blf_mono_font, dx, 6, 0); 00213 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00214 dx += BLF_width(blf_mono_font, str); 00215 00216 if(channels == 4) { 00217 glColor3ub(255, 255, 255); 00218 if (fp) 00219 sprintf(str, " A:%-.4f", fp[3]); 00220 else if (cp) 00221 sprintf(str, " A:%-3d", cp[3]); 00222 else 00223 sprintf(str, "- "); 00224 BLF_position(blf_mono_font, dx, 6, 0); 00225 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00226 dx += BLF_width(blf_mono_font, str); 00227 } 00228 } 00229 00230 /* color rectangle */ 00231 if (channels==1) { 00232 if (fp) 00233 col[0] = col[1] = col[2] = fp[0]; 00234 else if (cp) 00235 col[0] = col[1] = col[2] = (float)cp[0]/255.0f; 00236 else 00237 col[0] = col[1] = col[2] = 0.0f; 00238 } 00239 else if (channels==3) { 00240 if (fp) 00241 copy_v3_v3(col, fp); 00242 else if (cp) { 00243 col[0] = (float)cp[0]/255.0f; 00244 col[1] = (float)cp[1]/255.0f; 00245 col[2] = (float)cp[2]/255.0f; 00246 } 00247 else 00248 zero_v3(col); 00249 } 00250 else if (channels==4) { 00251 if (fp) 00252 copy_v4_v4(col, fp); 00253 else if (cp) { 00254 col[0] = (float)cp[0]/255.0f; 00255 col[1] = (float)cp[1]/255.0f; 00256 col[2] = (float)cp[2]/255.0f; 00257 col[3] = (float)cp[3]/255.0f; 00258 } 00259 else 00260 zero_v4(col); 00261 } 00262 if (color_manage) { 00263 linearrgb_to_srgb_v3_v3(finalcol, col); 00264 finalcol[3] = col[3]; 00265 } 00266 else { 00267 copy_v4_v4(finalcol, col); 00268 } 00269 glDisable(GL_BLEND); 00270 glColor3fv(finalcol); 00271 dx += 5; 00272 glBegin(GL_QUADS); 00273 glVertex2f(dx, 3); 00274 glVertex2f(dx, 17); 00275 glVertex2f(dx+30, 17); 00276 glVertex2f(dx+30, 3); 00277 glEnd(); 00278 dx += 35; 00279 00280 glColor3ub(255, 255, 255); 00281 if(channels == 1) { 00282 if (fp) { 00283 rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val); 00284 rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v); 00285 } 00286 else if (cp) { 00287 rgb_to_hsv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &hue, &sat, &val); 00288 rgb_to_yuv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &lum, &u, &v); 00289 } 00290 00291 sprintf(str, "V:%-.4f", val); 00292 BLF_position(blf_mono_font, dx, 6, 0); 00293 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00294 dx += BLF_width(blf_mono_font, str); 00295 00296 sprintf(str, " L:%-.4f", lum); 00297 BLF_position(blf_mono_font, dx, 6, 0); 00298 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00299 dx += BLF_width(blf_mono_font, str); 00300 } 00301 else if(channels >= 3) { 00302 if (fp) { 00303 rgb_to_hsv(fp[0], fp[1], fp[2], &hue, &sat, &val); 00304 rgb_to_yuv(fp[0], fp[1], fp[2], &lum, &u, &v); 00305 } 00306 else if (cp) { 00307 rgb_to_hsv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &hue, &sat, &val); 00308 rgb_to_yuv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &lum, &u, &v); 00309 } 00310 00311 sprintf(str, "H:%-.4f", hue); 00312 BLF_position(blf_mono_font, dx, 6, 0); 00313 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00314 dx += BLF_width(blf_mono_font, str); 00315 00316 sprintf(str, " S:%-.4f", sat); 00317 BLF_position(blf_mono_font, dx, 6, 0); 00318 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00319 dx += BLF_width(blf_mono_font, str); 00320 00321 sprintf(str, " V:%-.4f", val); 00322 BLF_position(blf_mono_font, dx, 6, 0); 00323 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00324 dx += BLF_width(blf_mono_font, str); 00325 00326 sprintf(str, " L:%-.4f", lum); 00327 BLF_position(blf_mono_font, dx, 6, 0); 00328 BLF_draw_ascii(blf_mono_font, str, sizeof(str)); 00329 dx += BLF_width(blf_mono_font, str); 00330 } 00331 00332 (void)dx; 00333 } 00334 00335 /* image drawing */ 00336 00337 static void draw_image_grid(ARegion *ar, float zoomx, float zoomy) 00338 { 00339 float gridsize, gridstep= 1.0f/32.0f; 00340 float fac, blendfac; 00341 int x1, y1, x2, y2; 00342 00343 /* the image is located inside (0,0),(1, 1) as set by view2d */ 00344 UI_ThemeColorShade(TH_BACK, 20); 00345 00346 UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x1, &y1); 00347 UI_view2d_to_region_no_clip(&ar->v2d, 1.0f, 1.0f, &x2, &y2); 00348 glRectf(x1, y1, x2, y2); 00349 00350 /* gridsize adapted to zoom level */ 00351 gridsize= 0.5f*(zoomx+zoomy); 00352 if(gridsize<=0.0f) return; 00353 00354 if(gridsize<1.0f) { 00355 while(gridsize<1.0f) { 00356 gridsize*= 4.0f; 00357 gridstep*= 4.0f; 00358 } 00359 } 00360 else { 00361 while(gridsize>=4.0f) { 00362 gridsize/= 4.0f; 00363 gridstep/= 4.0f; 00364 } 00365 } 00366 00367 /* the fine resolution level */ 00368 blendfac= 0.25f*gridsize - floorf(0.25f*gridsize); 00369 CLAMP(blendfac, 0.0f, 1.0f); 00370 UI_ThemeColorShade(TH_BACK, (int)(20.0f*(1.0f-blendfac))); 00371 00372 fac= 0.0f; 00373 glBegin(GL_LINES); 00374 while(fac<1.0f) { 00375 glVertex2f(x1, y1*(1.0f-fac) + y2*fac); 00376 glVertex2f(x2, y1*(1.0f-fac) + y2*fac); 00377 glVertex2f(x1*(1.0f-fac) + x2*fac, y1); 00378 glVertex2f(x1*(1.0f-fac) + x2*fac, y2); 00379 fac+= gridstep; 00380 } 00381 00382 /* the large resolution level */ 00383 UI_ThemeColor(TH_BACK); 00384 00385 fac= 0.0f; 00386 while(fac<1.0f) { 00387 glVertex2f(x1, y1*(1.0f-fac) + y2*fac); 00388 glVertex2f(x2, y1*(1.0f-fac) + y2*fac); 00389 glVertex2f(x1*(1.0f-fac) + x2*fac, y1); 00390 glVertex2f(x1*(1.0f-fac) + x2*fac, y2); 00391 fac+= 4.0f*gridstep; 00392 } 00393 glEnd(); 00394 } 00395 00396 static void sima_draw_alpha_backdrop(float x1, float y1, float xsize, float ysize, float zoomx, float zoomy, unsigned char col1[3], unsigned char col2[3]) 00397 { 00398 GLubyte checker_stipple[32*32/8] = 00399 { 00400 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \ 00401 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \ 00402 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \ 00403 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \ 00404 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \ 00405 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \ 00406 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \ 00407 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \ 00408 }; 00409 00410 glColor3ubv(col1); 00411 glRectf(x1, y1, x1 + zoomx*xsize, y1 + zoomy*ysize); 00412 glColor3ubv(col2); 00413 00414 glEnable(GL_POLYGON_STIPPLE); 00415 glPolygonStipple(checker_stipple); 00416 glRectf(x1, y1, x1 + zoomx*xsize, y1 + zoomy*ysize); 00417 glDisable(GL_POLYGON_STIPPLE); 00418 } 00419 00420 static void sima_draw_alpha_pixels(float x1, float y1, int rectx, int recty, unsigned int *recti) 00421 { 00422 00423 /* swap bytes, so alpha is most significant one, then just draw it as luminance int */ 00424 if(ENDIAN_ORDER == B_ENDIAN) 00425 glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); 00426 00427 glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_UNSIGNED_INT, recti); 00428 glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); 00429 } 00430 00431 static void sima_draw_alpha_pixelsf(float x1, float y1, int rectx, int recty, float *rectf) 00432 { 00433 float *trectf= MEM_mallocN(rectx*recty*4, "temp"); 00434 int a, b; 00435 00436 for(a= rectx*recty -1, b= 4*a+3; a>=0; a--, b-=4) 00437 trectf[a]= rectf[b]; 00438 00439 glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_FLOAT, trectf); 00440 MEM_freeN(trectf); 00441 /* ogl trick below is slower... (on ATI 9600) */ 00442 // glColorMask(1, 0, 0, 0); 00443 // glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+3); 00444 // glColorMask(0, 1, 0, 0); 00445 // glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+2); 00446 // glColorMask(0, 0, 1, 0); 00447 // glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+1); 00448 // glColorMask(1, 1, 1, 1); 00449 } 00450 00451 static void sima_draw_zbuf_pixels(float x1, float y1, int rectx, int recty, int *recti) 00452 { 00453 /* zbuffer values are signed, so we need to shift color range */ 00454 glPixelTransferf(GL_RED_SCALE, 0.5f); 00455 glPixelTransferf(GL_GREEN_SCALE, 0.5f); 00456 glPixelTransferf(GL_BLUE_SCALE, 0.5f); 00457 glPixelTransferf(GL_RED_BIAS, 0.5f); 00458 glPixelTransferf(GL_GREEN_BIAS, 0.5f); 00459 glPixelTransferf(GL_BLUE_BIAS, 0.5f); 00460 00461 glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_INT, recti); 00462 00463 glPixelTransferf(GL_RED_SCALE, 1.0f); 00464 glPixelTransferf(GL_GREEN_SCALE, 1.0f); 00465 glPixelTransferf(GL_BLUE_SCALE, 1.0f); 00466 glPixelTransferf(GL_RED_BIAS, 0.0f); 00467 glPixelTransferf(GL_GREEN_BIAS, 0.0f); 00468 glPixelTransferf(GL_BLUE_BIAS, 0.0f); 00469 } 00470 00471 static void sima_draw_zbuffloat_pixels(Scene *scene, float x1, float y1, int rectx, int recty, float *rect_float) 00472 { 00473 float bias, scale, *rectf, clipend; 00474 int a; 00475 00476 if(scene->camera && scene->camera->type==OB_CAMERA) { 00477 bias= ((Camera *)scene->camera->data)->clipsta; 00478 clipend= ((Camera *)scene->camera->data)->clipend; 00479 scale= 1.0f/(clipend-bias); 00480 } 00481 else { 00482 bias= 0.1f; 00483 scale= 0.01f; 00484 clipend= 100.0f; 00485 } 00486 00487 rectf= MEM_mallocN(rectx*recty*4, "temp"); 00488 for(a= rectx*recty -1; a>=0; a--) { 00489 if(rect_float[a]>clipend) 00490 rectf[a]= 0.0f; 00491 else if(rect_float[a]<bias) 00492 rectf[a]= 1.0f; 00493 else { 00494 rectf[a]= 1.0f - (rect_float[a]-bias)*scale; 00495 rectf[a]*= rectf[a]; 00496 } 00497 } 00498 glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_FLOAT, rectf); 00499 00500 MEM_freeN(rectf); 00501 } 00502 00503 static void draw_image_buffer(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy) 00504 { 00505 int x, y; 00506 int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; 00507 00508 /* set zoom */ 00509 glPixelZoom(zoomx, zoomy); 00510 00511 /* find window pixel coordinates of origin */ 00512 UI_view2d_to_region_no_clip(&ar->v2d, fx, fy, &x, &y); 00513 00514 /* this part is generic image display */ 00515 if(sima->flag & SI_SHOW_ALPHA) { 00516 if(ibuf->rect) 00517 sima_draw_alpha_pixels(x, y, ibuf->x, ibuf->y, ibuf->rect); 00518 else if(ibuf->rect_float && ibuf->channels==4) 00519 sima_draw_alpha_pixelsf(x, y, ibuf->x, ibuf->y, ibuf->rect_float); 00520 } 00521 else if(sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels==1))) { 00522 if(ibuf->zbuf) 00523 sima_draw_zbuf_pixels(x, y, ibuf->x, ibuf->y, ibuf->zbuf); 00524 else if(ibuf->zbuf_float) 00525 sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->zbuf_float); 00526 else if(ibuf->channels==1) 00527 sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float); 00528 } 00529 else { 00530 if(sima->flag & SI_USE_ALPHA) { 00531 unsigned char col1[3]= {100, 100, 100}, col2[3]= {160, 160, 160}; 00532 sima_draw_alpha_backdrop(x, y, ibuf->x, ibuf->y, zoomx, zoomy, col1, col2); 00533 00534 glEnable(GL_BLEND); 00535 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00536 } 00537 00538 /* we don't draw floats buffers directly but 00539 * convert them, and optionally apply curves */ 00540 image_verify_buffer_float(ima, ibuf, color_manage); 00541 00542 if(ibuf->rect) 00543 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); 00544 /*else 00545 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float);*/ 00546 00547 if(sima->flag & SI_USE_ALPHA) 00548 glDisable(GL_BLEND); 00549 } 00550 00551 /* reset zoom */ 00552 glPixelZoom(1.0f, 1.0f); 00553 } 00554 00555 static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, short endx, short endy) 00556 { 00557 unsigned int *rt, *rp, *rectmain; 00558 short y, heigth, len; 00559 00560 /* the right offset in rectot */ 00561 00562 rt= ibuf->rect+ (starty*ibuf->x+ startx); 00563 00564 len= (endx-startx); 00565 heigth= (endy-starty); 00566 00567 rp=rectmain= MEM_mallocN(heigth*len*sizeof(int), "rect"); 00568 00569 for(y=0; y<heigth; y++) { 00570 memcpy(rp, rt, len*4); 00571 rt+= ibuf->x; 00572 rp+= len; 00573 } 00574 return rectmain; 00575 } 00576 00577 static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy) 00578 { 00579 unsigned int *rect; 00580 int dx, dy, sx, sy, x, y; 00581 int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; 00582 00583 /* verify valid values, just leave this a while */ 00584 if(ima->xrep<1) return; 00585 if(ima->yrep<1) return; 00586 00587 glPixelZoom(zoomx, zoomy); 00588 00589 if(sima->curtile >= ima->xrep*ima->yrep) 00590 sima->curtile = ima->xrep*ima->yrep - 1; 00591 00592 /* create char buffer from float if needed */ 00593 image_verify_buffer_float(ima, ibuf, color_manage); 00594 00595 /* retrieve part of image buffer */ 00596 dx= ibuf->x/ima->xrep; 00597 dy= ibuf->y/ima->yrep; 00598 sx= (sima->curtile % ima->xrep)*dx; 00599 sy= (sima->curtile / ima->xrep)*dy; 00600 rect= get_part_from_ibuf(ibuf, sx, sy, sx+dx, sy+dy); 00601 00602 /* draw repeated */ 00603 for(sy=0; sy+dy<=ibuf->y; sy+= dy) { 00604 for(sx=0; sx+dx<=ibuf->x; sx+= dx) { 00605 UI_view2d_to_region_no_clip(&ar->v2d, fx + (float)sx/(float)ibuf->x, fy + (float)sy/(float)ibuf->y, &x, &y); 00606 00607 glaDrawPixelsSafe(x, y, dx, dy, dx, GL_RGBA, GL_UNSIGNED_BYTE, rect); 00608 } 00609 } 00610 00611 glPixelZoom(1.0f, 1.0f); 00612 00613 MEM_freeN(rect); 00614 } 00615 00616 static void draw_image_buffer_repeated(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float zoomx, float zoomy) 00617 { 00618 const double time_current= PIL_check_seconds_timer(); 00619 00620 const int xmax= ceil(ar->v2d.cur.xmax); 00621 const int ymax= ceil(ar->v2d.cur.ymax); 00622 const int xmin= floor(ar->v2d.cur.xmin); 00623 const int ymin= floor(ar->v2d.cur.ymin); 00624 00625 int x; 00626 00627 for(x=xmin; x<xmax; x++) { 00628 int y; 00629 for(y=ymin; y<ymax; y++) { 00630 if(ima && (ima->tpageflag & IMA_TILES)) 00631 draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, x, y, zoomx, zoomy); 00632 else 00633 draw_image_buffer(sima, ar, scene, ima, ibuf, x, y, zoomx, zoomy); 00634 00635 /* only draw until running out of time */ 00636 if((PIL_check_seconds_timer() - time_current) > 0.25) 00637 return; 00638 } 00639 } 00640 } 00641 00642 /* draw uv edit */ 00643 00644 /* draw grease pencil */ 00645 void draw_image_grease_pencil(bContext *C, short onlyv2d) 00646 { 00647 /* draw in View2D space? */ 00648 if (onlyv2d) { 00649 /* assume that UI_view2d_ortho(C) has been called... */ 00650 SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C); 00651 void *lock; 00652 ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock); 00653 00654 /* draw grease-pencil ('image' strokes) */ 00655 //if (sima->flag & SI_DISPGP) 00656 draw_gpencil_2dimage(C, ibuf); 00657 00658 ED_space_image_release_buffer(sima, lock); 00659 } 00660 else { 00661 /* assume that UI_view2d_restore(C) has been called... */ 00662 //SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C); 00663 00664 /* draw grease-pencil ('screen' strokes) */ 00665 //if (sima->flag & SI_DISPGP) 00666 draw_gpencil_view2d(C, 0); 00667 } 00668 } 00669 00670 /* XXX becomes WM paint cursor */ 00671 #if 0 00672 static void draw_image_view_tool(Scene *scene) 00673 { 00674 ToolSettings *settings= scene->toolsettings; 00675 Brush *brush= settings->imapaint.brush; 00676 int mval[2]; 00677 float radius; 00678 int draw= 0; 00679 00680 if(brush) { 00681 if(settings->imapaint.flag & IMAGEPAINT_DRAWING) { 00682 if(settings->imapaint.flag & IMAGEPAINT_DRAW_TOOL_DRAWING) 00683 draw= 1; 00684 } 00685 else if(settings->imapaint.flag & IMAGEPAINT_DRAW_TOOL) 00686 draw= 1; 00687 00688 if(draw) { 00689 getmouseco_areawin(mval); 00690 00691 radius= brush_size(brush)*G.sima->zoom; 00692 fdrawXORcirc(mval[0], mval[1], radius); 00693 00694 if (brush->innerradius != 1.0) { 00695 radius *= brush->innerradius; 00696 fdrawXORcirc(mval[0], mval[1], radius); 00697 } 00698 } 00699 } 00700 } 00701 #endif 00702 00703 static unsigned char *get_alpha_clone_image(Scene *scene, int *width, int *height) 00704 { 00705 Brush *brush = paint_brush(&scene->toolsettings->imapaint.paint); 00706 ImBuf *ibuf; 00707 unsigned int size, alpha; 00708 unsigned char *rect, *cp; 00709 00710 if(!brush || !brush->clone.image) 00711 return NULL; 00712 00713 ibuf= BKE_image_get_ibuf(brush->clone.image, NULL); 00714 00715 if(!ibuf || !ibuf->rect) 00716 return NULL; 00717 00718 rect= MEM_dupallocN(ibuf->rect); 00719 if(!rect) 00720 return NULL; 00721 00722 *width= ibuf->x; 00723 *height= ibuf->y; 00724 00725 size= (*width)*(*height); 00726 alpha= (unsigned char)255*brush->clone.alpha; 00727 cp= rect; 00728 00729 while(size-- > 0) { 00730 cp[3]= alpha; 00731 cp += 4; 00732 } 00733 00734 return rect; 00735 } 00736 00737 static void draw_image_paint_helpers(ARegion *ar, Scene *scene, float zoomx, float zoomy) 00738 { 00739 Brush *brush; 00740 int x, y, w, h; 00741 unsigned char *clonerect; 00742 00743 brush= paint_brush(&scene->toolsettings->imapaint.paint); 00744 00745 if(brush && (brush->imagepaint_tool == PAINT_TOOL_CLONE)) { 00746 /* this is not very efficient, but glDrawPixels doesn't allow 00747 drawing with alpha */ 00748 clonerect= get_alpha_clone_image(scene, &w, &h); 00749 00750 if(clonerect) { 00751 UI_view2d_to_region_no_clip(&ar->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y); 00752 00753 glPixelZoom(zoomx, zoomy); 00754 00755 glEnable(GL_BLEND); 00756 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00757 glaDrawPixelsSafe(x, y, w, h, w, GL_RGBA, GL_UNSIGNED_BYTE, clonerect); 00758 glDisable(GL_BLEND); 00759 00760 glPixelZoom(1.0, 1.0); 00761 00762 MEM_freeN(clonerect); 00763 } 00764 } 00765 } 00766 00767 /* draw main image area */ 00768 00769 void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) 00770 { 00771 Image *ima; 00772 ImBuf *ibuf; 00773 float zoomx, zoomy; 00774 int show_viewer, show_render; 00775 void *lock; 00776 00777 /* XXX can we do this in refresh? */ 00778 #if 0 00779 what_image(sima); 00780 00781 if(sima->image) { 00782 ED_image_aspect(sima->image, &xuser_asp, &yuser_asp); 00783 00784 /* UGLY hack? until now iusers worked fine... but for flipbook viewer we need this */ 00785 if(sima->image->type==IMA_TYPE_COMPOSITE) { 00786 ImageUser *iuser= ntree_get_active_iuser(scene->nodetree); 00787 if(iuser) { 00788 BKE_image_user_calc_imanr(iuser, scene->r.cfra, 0); 00789 sima->iuser= *iuser; 00790 } 00791 } 00792 /* and we check for spare */ 00793 ibuf= ED_space_image_buffer(sima); 00794 } 00795 #endif 00796 00797 /* retrieve the image and information about it */ 00798 ima= ED_space_image(sima); 00799 ED_space_image_zoom(sima, ar, &zoomx, &zoomy); 00800 ibuf= ED_space_image_acquire_buffer(sima, &lock); 00801 00802 show_viewer= (ima && ima->source == IMA_SRC_VIEWER); 00803 show_render= (show_viewer && ima->type == IMA_TYPE_R_RESULT); 00804 00805 /* draw the image or grid */ 00806 if(ibuf==NULL) 00807 draw_image_grid(ar, zoomx, zoomy); 00808 else if(sima->flag & SI_DRAW_TILE) 00809 draw_image_buffer_repeated(sima, ar, scene, ima, ibuf, zoomx, zoomy); 00810 else if(ima && (ima->tpageflag & IMA_TILES)) 00811 draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, 0.0f, 0.0, zoomx, zoomy); 00812 else 00813 draw_image_buffer(sima, ar, scene, ima, ibuf, 0.0f, 0.0f, zoomx, zoomy); 00814 00815 /* paint helpers */ 00816 if(sima->flag & SI_DRAWTOOL) 00817 draw_image_paint_helpers(ar, scene, zoomx, zoomy); 00818 00819 00820 /* XXX integrate this code */ 00821 #if 0 00822 if(ibuf) { 00823 float xoffs=0.0f, yoffs= 0.0f; 00824 00825 if(image_preview_active(sa, &xim, &yim)) { 00826 xoffs= scene->r.disprect.xmin; 00827 yoffs= scene->r.disprect.ymin; 00828 glColor3ub(0,0,0); 00829 calc_image_view(sima, 'f'); 00830 myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); 00831 glRectf(0.0f, 0.0f, 1.0f, 1.0f); 00832 glLoadIdentity(); 00833 } 00834 } 00835 #endif 00836 00837 ED_space_image_release_buffer(sima, lock); 00838 00839 /* render info */ 00840 if(ima && show_render) 00841 draw_render_info(scene, ima, ar); 00842 } 00843