/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 2002 by NaN Holding BV. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ /* drawimage.c juli 96 GRAPHICS * * * */ #include "blender.h" #include "graphics.h" #include "sector.h" void rectwrite_part(int winxmin, int winymin, int winxmax, int winymax, int x1, int y1, int xim, int yim, float zoom, ulong *rect) { int cx, cy, oldxim, x2, y2; oldxim= xim; xim--; yim--; /* coordinaten hoe 't op scherm komt */ x2= x1+ zoom*xim; y2= y1+ zoom*yim; /* partiele clip */ if(x1winxmax) { cx= x2-winxmax; cx/= zoom; xim-= cx; } if(y2>winymax) { cy= y2-winymax; cy/= zoom; yim-= cy; } if(xim<=0) return; if(yim<=0) return; /* geeft aan dat per scanline lrectwrite, oldxim in de rect verder gelezen wordt */ pixmode(PM_STRIDE, oldxim); rectzoom(zoom, zoom); lrectwrite(x1, y1, x1+xim, y1+yim, rect); rectzoom(1.0, 1.0); pixmode(PM_STRIDE, 0); } /* nog nergens gebuikt? */ void set_imagespace(Image *ima, int zoom) { ScrArea *sa; SpaceImage *sima; /* welke area? */ sa= G.curscreen->areabase.first; while(sa) { if(sa->spacetype==SPACE_IMAGE) { break; } sa= sa->next; } if(sa) { addqueue(sa->win, REDRAW, 1); addqueue(sa->headwin, REDRAW, 1); sima= sa->spacedata.first; sima->image= ima; if(zoom) sima->zoom= zoom; } } void calc_image_view(SpaceImage *sima, char mode) { int xim=100, yim=100; int x1, y1; float zoom; if(sima->image && sima->image->ibuf) { xim= sima->image->ibuf->x; yim= sima->image->ibuf->y; } sima->v2d.tot.xmin= 0; sima->v2d.tot.ymin= 0; sima->v2d.tot.xmax= xim; sima->v2d.tot.ymax= yim; sima->v2d.mask.xmin= sima->v2d.mask.ymin= 0; sima->v2d.mask.xmax= curarea->winx; sima->v2d.mask.ymax= curarea->winy; /* welk deel van de imageruimte zien we: */ /* zelfde berekening als lrectwrite: plek linksonder */ x1= curarea->winrct.xmin+(curarea->winx-sima->zoom*xim)/2; y1= curarea->winrct.ymin+(curarea->winy-sima->zoom*yim)/2; x1-= sima->zoom*sima->xof; y1-= sima->zoom*sima->yof; /* float! */ zoom= sima->zoom; /* relatieve afbeeld links */ sima->v2d.cur.xmin= ((curarea->winrct.xmin - (float)x1)/zoom); sima->v2d.cur.xmax= sima->v2d.cur.xmin + ((float)curarea->winx/zoom); /* relatieve afbeeld links */ sima->v2d.cur.ymin= ((curarea->winrct.ymin-(float)y1)/zoom); sima->v2d.cur.ymax= sima->v2d.cur.ymin + ((float)curarea->winy/zoom); if(mode=='s') { xim= 32768.0/xim; yim= 32768.0/yim; sima->v2d.cur.xmin*= xim; sima->v2d.cur.xmax*= xim; sima->v2d.cur.ymin*= yim; sima->v2d.cur.ymax*= yim; } } void what_image(SpaceImage *sima) { extern TFace *lasttface; /* editsector.c */ Mesh *me; if(sima->mode==SI_TEXTURE) { if(G.f & G_FACESELECT) { sima->image= 0; me= get_mesh(OBACT); set_lasttface(); if(me && me->tface && lasttface) { if(lasttface->mode & TF_TEX) { sima->image= lasttface->tpage; if(sima->flag & SI_EDITTILE); else sima->curtile= lasttface->tile; if(sima->image) { if(lasttface->mode & TF_TILES) sima->image->tpageflag |= IMA_TILES; else sima->image->tpageflag &= ~IMA_TILES; } } } } } } void image_changed(SpaceImage *sima, int dotile) { TFace *tface; Mesh *me; int a; if(sima->mode==SI_TEXTURE) { if(G.f & G_FACESELECT) { me= get_mesh(OBACT); if(me && me->tface) { tface= me->tface; a= me->totface; while(a--) { if(tface->flag & SELECT) { if(dotile==2) { tface->mode &= ~TF_TILES; } else { tface->tpage= sima->image; tface->mode |= TF_TEX; if(dotile) tface->tile= sima->curtile; } if(sima->image) { if(sima->image->tpageflag & IMA_TILES) tface->mode |= TF_TILES; else tface->mode &= ~TF_TILES; if(sima->image->id.us==0) sima->image->id.us= 1; } } tface++; } allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSGAME, 0); } } } } void uvco_to_areaco(short *vec, short *mval) { float x, y; mval[0]= 3200; x= (vec[0] - G.v2d->cur.xmin)/(G.v2d->cur.xmax-G.v2d->cur.xmin); if(x>=0.0 && x<=1.0) { y= (vec[1] - G.v2d->cur.ymin)/(G.v2d->cur.ymax-G.v2d->cur.ymin); if(y>=0.0 && y<=1.0) { mval[0]= G.v2d->mask.xmin + x*(G.v2d->mask.xmax-G.v2d->mask.xmin); mval[1]= G.v2d->mask.ymin + y*(G.v2d->mask.ymax-G.v2d->mask.ymin); } } } void uvco_to_areaco_noclip(short *vec, short *mval) { float x, y; mval[0]= 3200; x= (vec[0] - G.v2d->cur.xmin)/(G.v2d->cur.xmax-G.v2d->cur.xmin); y= (vec[1] - G.v2d->cur.ymin)/(G.v2d->cur.ymax-G.v2d->cur.ymin); x= G.v2d->mask.xmin + x*(G.v2d->mask.xmax-G.v2d->mask.xmin); y= G.v2d->mask.ymin + y*(G.v2d->mask.ymax-G.v2d->mask.ymin); if(x<-32760) mval[0]= -32760; else if(x>32760) mval[0]= 32760; else mval[0]= x; if(y<-32760) mval[1]= -32760; else if(y>32760) mval[1]= 32760; else mval[1]= y; } void draw_tfaces() { TFace *tface; MFace *mface; Mesh *me; ulong col; int a; short mval[2]; if(G.f & G_FACESELECT) { me= get_mesh(OBACT); if(me && me->tface) { calc_image_view(G.sima, 's'); /* short */ ortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); tface= me->tface; mface= me->mface; a= me->totface; while(a--) { if(mface->v3 && (tface->flag & SELECT) ) { cpack(0x0); bgnclosedline(); v2s( tface->uv[0] ); v2s( tface->uv[1] ); v2s( tface->uv[2] ); if(mface->v4) v2s( tface->uv[3] ); endclosedline(); setlinestyle(1); /* kleuren: R=x G=y */ if(tface->flag & ACTIVE) cpack(0xFF00); else cpack(0xFFFFFF); bgnline(); v2s( tface->uv[0] ); v2s( tface->uv[1] ); endline(); if(tface->flag & ACTIVE) cpack(0xFF); else cpack(0xFFFFFF); bgnline(); v2s( tface->uv[0] ); if(mface->v4) v2s( tface->uv[3] ); else v2s( tface->uv[2] ); endline(); cpack(0xFFFFFF); bgnline(); v2s( tface->uv[1] ); v2s( tface->uv[2] ); if(mface->v4) v2s( tface->uv[3] ); endline(); setlinestyle(0); uvco_to_areaco(tface->uv[0], mval); if(tface->flag & TF_SEL1) col= 0x77FFFF; else col= 0xFF70FF; tekenrect_col(3, mval[0], mval[1], col); uvco_to_areaco(tface->uv[1], mval); if(tface->flag & TF_SEL2) col= 0x77FFFF; else col= 0xFF70FF; tekenrect_col(3, mval[0], mval[1], col); uvco_to_areaco(tface->uv[2], mval); if(tface->flag & TF_SEL3) col= 0x77FFFF; else col= 0xFF70FF; tekenrect_col(3, mval[0], mval[1], col); if(mface->v4) { uvco_to_areaco(tface->uv[3], mval); if(tface->flag & TF_SEL4) col= 0x77FFFF; else col= 0xFF70FF; tekenrect_col(3, mval[0], mval[1], col); } } tface++; mface++; } } } } ulong *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, short endx, short endy) { ulong *rt, *rp, *rectmain; short y, heigth, len; /* de juiste offset in rectot */ rt= ibuf->rect+ (starty*ibuf->x+ startx); len= (endx-startx); heigth= (endy-starty); rp=rectmain= mallocN(heigth*len*4, "rect"); for(y=0; yx; rp+= len; } return rectmain; } void drawimagespace() { ImBuf *ibuf; TFace *tface; ulong *rect; int x1, y1, xmin, xmax, ymin, ymax; short sx, sy, dx, dy; cpack(0x303030); clear(); curarea->win_swap= 1; what_image(G.sima); if(G.sima->image==0) return; xmin= curarea->winrct.xmin; xmax= curarea->winrct.xmax; ymin= curarea->winrct.ymin; ymax= curarea->winrct.ymax; if(G.sima->image->ibuf==0) G.sima->image->ibuf = loadiffname(G.sima->image->name , LI_rect); ibuf= G.sima->image->ibuf; if(ibuf==0 || ibuf->rect==0) return; /* plek berekenen */ x1= xmin+(curarea->winx-G.sima->zoom*ibuf->x)/2; y1= ymin+(curarea->winy-G.sima->zoom*ibuf->y)/2; x1-= G.sima->zoom*G.sima->xof; y1-= G.sima->zoom*G.sima->yof; if(G.sima->flag & SI_EDITTILE) { rectwrite_part(xmin, ymin, xmax, ymax, x1, y1, ibuf->x, ibuf->y, (float)G.sima->zoom, ibuf->rect); dx= ibuf->x/G.sima->image->xrep; dy= ibuf->y/G.sima->image->yrep; sy= (G.sima->curtile / G.sima->image->xrep); sx= G.sima->curtile - sy*G.sima->image->xrep; sx*= dx; sy*= dy; calc_image_view(G.sima, 'p'); /* pixel */ ortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); cpack(0x0); sboxs(sx, sy, sx+dx-1, sy+dy-1); cpack(0xFFFFFF); sboxs(sx+1, sy+1, sx+dx, sy+dy); } else if(G.sima->mode==SI_TEXTURE) { if(G.sima->image->tpageflag & IMA_TILES) { /* eventjes laten staan */ if(G.sima->image->xrep<1) return; if(G.sima->image->yrep<1) return; if(G.sima->curtile >= G.sima->image->xrep*G.sima->image->yrep) G.sima->curtile = G.sima->image->xrep*G.sima->image->yrep - 1; dx= ibuf->x/G.sima->image->xrep; dy= ibuf->y/G.sima->image->yrep; sy= (G.sima->curtile / G.sima->image->xrep); sx= G.sima->curtile - sy*G.sima->image->xrep; sx*= dx; sy*= dy; rect= get_part_from_ibuf(ibuf, sx, sy, sx+dx, sy+dy); /* rect= ibuf->rect; */ for(sy= 0; sy+dy<=ibuf->y; sy+= dy) { for(sx= 0; sx+dx<=ibuf->x; sx+= dx) { rectwrite_part(xmin, ymin, xmax, ymax, x1+sx*G.sima->zoom, y1+sy*G.sima->zoom, dx, dy, (float)G.sima->zoom, rect); } } freeN(rect); } else rectwrite_part(xmin, ymin, xmax, ymax, x1, y1, ibuf->x, ibuf->y, (float)G.sima->zoom, ibuf->rect); draw_tfaces(); } calc_image_view(G.sima, 's'); /* short */ } void image_viewmove() { short mval[2], mvalo[2], xof, yof; getmouseco_sc(mvalo); while(getbutton(MIDDLEMOUSE) || getbutton(LEFTMOUSE) ) { getmouseco_sc(mval); xof= (mvalo[0]-mval[0])/G.sima->zoom; yof= (mvalo[1]-mval[1])/G.sima->zoom; if(xof || yof) { G.sima->xof+= xof; G.sima->yof+= yof; mvalo[0]= mval[0]; mvalo[1]= mval[1]; curarea->windraw(); screen_swapbuffers(); } else sginap(2); } } void image_home() { if(curarea->spacetype!=SPACE_IMAGE) return; if(G.sima->image==0 || G.sima->image->ibuf==0) return; G.sima->zoom= 1; G.sima->xof= G.sima->yof= 0; calc_image_view(G.sima, 'p'); addqueue(curarea->win, REDRAW, 1); }