/** * $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 * * * * Version: $Id: drawimage.c,v 1.5 2000/07/21 09:05:23 nzc Exp $ */ #include "blender.h" #include "graphics.h" /* Modules used */ #include "render.h" void rectwrite_part(int winxmin, int winymin, int winxmax, int winymax, int x1, int y1, int xim, int yim, float zoomx, float zoomy, uint *rect) { int cx, cy, oldxim, x2, y2; oldxim= xim; xim--; yim--; /* coordinaten hoe 't op scherm komt */ x2= x1+ zoomx*xim; y2= y1+ zoomy*yim; /* partiele clip */ if(x1=winxmax) { cx= x2-winxmax; cx/= zoomx; xim-= cx+3; } if(y2>=winymax) { cy= y2-winymax; cy/= zoomy; yim-= cy+3; } if(xim<=0) return; if(yim<=0) return; if(G.curscreen->winakt!= R.win) { /* dit is vanwege IRISGL, recten altijd in screen coordinaten */ winset(G.curscreen->mainwin); glScissor(winxmin, winymin, winxmax-winxmin+1, winymax-winymin+1); } glPixelStorei(GL_UNPACK_ROW_LENGTH, oldxim); glPixelZoom(zoomx, zoomy); glRasterPos2i(x1, y1); glDrawPixels(xim, yim, GL_RGBA, GL_UNSIGNED_BYTE, rect); glPixelZoom(1.0, 1.0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); if(G.curscreen->winakt!= R.win) winset(curarea->win); } /* 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) { float xim=256, yim=256; float 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=='f') { 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; /* editface.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(float *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(float *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); mval[0]= x; mval[1]= y; } void draw_tfaces() { TFace *tface; MFace *mface; Mesh *me; uint col; int a; glPointSize(2.0); if(G.f & G_FACESELECT) { me= get_mesh(OBACT); if(me && me->tface) { calc_image_view(G.sima, 'f'); /* float */ 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); glBegin(GL_LINE_LOOP); glVertex2fv( tface->uv[0] ); glVertex2fv( tface->uv[1] ); glVertex2fv( tface->uv[2] ); if(mface->v4) glVertex2fv( tface->uv[3] ); glEnd(); setlinestyle(2); /* kleuren: R=x G=y */ if(tface->flag & ACTIVE) cpack(0xFF00); else cpack(0xFFFFFF); glBegin(GL_LINE_STRIP); glVertex2fv( tface->uv[0] ); glVertex2fv( tface->uv[1] ); glEnd(); if(tface->flag & ACTIVE) cpack(0xFF); else cpack(0xFFFFFF); glBegin(GL_LINE_STRIP); glVertex2fv( tface->uv[0] ); if(mface->v4) glVertex2fv( tface->uv[3] ); else glVertex2fv( tface->uv[2] ); glEnd(); cpack(0xFFFFFF); glBegin(GL_LINE_STRIP); glVertex2fv( tface->uv[1] ); glVertex2fv( tface->uv[2] ); if(mface->v4) glVertex2fv( tface->uv[3] ); glEnd(); setlinestyle(0); glBegin(GL_POINTS); if(tface->flag & TF_SEL1) col= 0x77FFFF; else col= 0xFF70FF; cpack(col); glVertex2fv(tface->uv[0]); if(tface->flag & TF_SEL2) col= 0x77FFFF; else col= 0xFF70FF; cpack(col); glVertex2fv(tface->uv[1]); if(tface->flag & TF_SEL3) col= 0x77FFFF; else col= 0xFF70FF; cpack(col); glVertex2fv(tface->uv[2]); if(mface->v4) { if(tface->flag & TF_SEL4) col= 0x77FFFF; else col= 0xFF70FF; cpack(col); glVertex2fv(tface->uv[3]); } glEnd(); } tface++; mface++; } } } glPointSize(1.0); } uint *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, short endx, short endy) { uint *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*sizeof(int), "rect"); for(y=0; yx; rp+= len; } return rectmain; } void drawimagespace() { ImBuf *ibuf= NULL; uint *rect; int x1, y1, xmin, xmax, ymin, ymax; short sx, sy, dx, dy; glClearColor(.1875, .1875, .1875, 0.0); glClear(GL_COLOR_BUFFER_BIT); curarea->win_swap= WIN_BACK_OK; xmin= curarea->winrct.xmin; xmax= curarea->winrct.xmax; ymin= curarea->winrct.ymin; ymax= curarea->winrct.ymax; what_image(G.sima); if(G.sima->image) { if(G.sima->image->ibuf==0) { load_image(G.sima->image, IB_rect); } ibuf= G.sima->image->ibuf; } if(ibuf==0 || ibuf->rect==0) { calc_image_view(G.sima, 'f'); ortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); cpack(0x404040); glRectf(0.0, 0.0, 1.0, 1.0); draw_tfaces(); 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, (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); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glRects(sx, sy, sx+dx-1, sy+dy-1); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); cpack(0xFFFFFF); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glRects(sx+1, sy+1, sx+dx, sy+dy); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } 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, (float)G.sima->zoom, rect); } } freeN(rect); } else rectwrite_part(xmin, ymin, xmax, ymax, x1, y1, ibuf->x, ibuf->y, (float)G.sima->zoom,(float)G.sima->zoom, ibuf->rect); draw_tfaces(); } calc_image_view(G.sima, 'f'); /* float */ } void image_viewmove() { short mval[2], mvalo[2], xof, yof; getmouseco_sc(mvalo); while(get_mbut()&(L_MOUSE|M_MOUSE)) { 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 usleep(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); }