/** * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. The Blender * Foundation also sells licenses for use in proprietary software under * the Blender License. See http://www.blender.org/BL/ for information * about this. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * The Original Code is Copyright (C) 2001-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 ***** */ #include #ifdef WIN32 #include "BLI_winstuff.h" #endif #include "MEM_guardedalloc.h" #include "DNA_vec_types.h" #include "BIF_gl.h" #include "BIF_glutil.h" /* Invert line handling */ #define glToggle(mode, onoff) (((onoff)?glEnable:glDisable)(mode)) static void set_inverted_drawing(int enable) { glLogicOp(enable?GL_INVERT:GL_COPY); /* Use GL_BLEND_EQUATION_EXT on sgi (if we have it), * apparently GL_COLOR_LOGIC_OP doesn't work on O2? * Is this an sgi bug or our bug? */ #if defined(__sgi) && defined(GL_BLEND_EQUATION_EXT) glBlendEquationEXT(enable?GL_LOGIC_OP:GL_FUNC_ADD_EXT); glToggle(GL_BLEND, enable); #else glToggle(GL_COLOR_LOGIC_OP, enable); #endif glToggle(GL_DITHER, !enable); } void sdrawXORline(int x0, int y0, int x1, int y1) { if(x0==x1 && y0==y1) return; set_inverted_drawing(1); glBegin(GL_LINES); glVertex2i(x0, y0); glVertex2i(x1, y1); glEnd(); set_inverted_drawing(0); } void glutil_draw_front_xor_line(int x0, int y0, int x1, int y1) { glDrawBuffer(GL_FRONT); sdrawXORline(x0, y0, x1, y1); glFinish(); glDrawBuffer(GL_BACK); } void sdrawXORline4(int nr, int x0, int y0, int x1, int y1) { static short old[4][2][2]; static char flags[4]= {0, 0, 0, 0}; /* automatische onthoud, max 4 lijnen */ set_inverted_drawing(1); glBegin(GL_LINES); if(nr== -1) { /* flush */ for (nr=0; nr<4; nr++) { if (flags[nr]) { glVertex2sv(old[nr][0]); glVertex2sv(old[nr][1]); flags[nr]= 0; } } } else { if(nr>=0 && nr<4) { if(flags[nr]) { glVertex2sv(old[nr][0]); glVertex2sv(old[nr][1]); } old[nr][0][0]= x0; old[nr][0][1]= y0; old[nr][1][0]= x1; old[nr][1][1]= y1; flags[nr]= 1; } glVertex2i(x0, y0); glVertex2i(x1, y1); } glEnd(); set_inverted_drawing(0); } void sdrawXORcirc(short xofs, short yofs, float rad) { set_inverted_drawing(1); glPushMatrix(); glTranslatef(xofs, yofs, 0.0); glutil_draw_lined_arc(0.0, M_PI*2, rad, 20); glPopMatrix(); set_inverted_drawing(0); } void glutil_draw_filled_arc(float start, float angle, float radius, int nsegments) { int i; glBegin(GL_TRIANGLE_FAN); glVertex2f(0.0, 0.0); for (i=0; i=origin_x && y>=origin_y) { glRasterPos2f(x, y); glDrawPixels(img_w, img_h, GL_RGBA, GL_UNSIGNED_BYTE, uc_rect); } else { int old_row_length= glaGetOneInteger(GL_UNPACK_ROW_LENGTH); float xzoom= glaGetOneFloat(GL_ZOOM_X); float yzoom= glaGetOneFloat(GL_ZOOM_Y); /* The pixel space coordinate of the intersection of * the [zoomed] image with the origin. */ float ix= (origin_x-x)/xzoom; float iy= (origin_y-y)/yzoom; /* The maximum pixel amounts the image can cropped * without exceeding the origin. */ int off_x= floor((ix>origin_x)?ix:origin_x); int off_y= floor((iy>origin_y)?iy:origin_y); /* The zoomed space coordinate of the raster * position. */ float rast_x= x + off_x*xzoom; float rast_y= y + off_y*yzoom; if (off_xxmax - screen_rect->xmin; int sc_h= screen_rect->ymax - screen_rect->ymin; glViewport(screen_rect->xmin, screen_rect->ymin, sc_w, sc_h); glScissor(screen_rect->xmin, screen_rect->ymin, sc_w, sc_h); /* The 0.375 magic number is to shift the matrix so that * both raster and vertex integer coordinates fall at pixel * centers properly. For a longer discussion see the OpenGL * Programming Guide, Appendix H, Correctness Tips. */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, sc_w, 0.0, sc_h, -1, 1); glTranslatef(0.375, 0.375, 0.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } struct gla2DDrawInfo { int orig_vp[4], orig_sc[4]; float orig_projmat[16], orig_viewmat[16]; rcti screen_rect; rctf world_rect; float wo_to_sc[2]; }; gla2DDrawInfo *glaBegin2DDraw(rcti *screen_rect, rctf *world_rect) { gla2DDrawInfo *di= MEM_mallocN(sizeof(*di), "gla2DDrawInfo"); int sc_w, sc_h; float wo_w, wo_h; glGetIntegerv(GL_VIEWPORT, di->orig_vp); glGetIntegerv(GL_SCISSOR_BOX, di->orig_sc); glGetFloatv(GL_PROJECTION_MATRIX, di->orig_projmat); glGetFloatv(GL_MODELVIEW_MATRIX, di->orig_viewmat); di->screen_rect= *screen_rect; if (world_rect) { di->world_rect= *world_rect; } else { di->world_rect.xmin= di->screen_rect.xmin; di->world_rect.ymin= di->screen_rect.ymin; di->world_rect.xmax= di->screen_rect.xmax; di->world_rect.ymax= di->screen_rect.ymax; } sc_w= (di->screen_rect.xmax-di->screen_rect.xmin); sc_h= (di->screen_rect.ymax-di->screen_rect.ymin); wo_w= (di->world_rect.xmax-di->world_rect.xmin); wo_h= (di->world_rect.ymax-di->world_rect.ymin); di->wo_to_sc[0]= sc_w/wo_w; di->wo_to_sc[1]= sc_h/wo_h; glaDefine2DArea(&di->screen_rect); return di; } void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *sc_x_r, int *sc_y_r) { *sc_x_r= (wo_x - di->world_rect.xmin)*di->wo_to_sc[0]; *sc_y_r= (wo_y - di->world_rect.ymin)*di->wo_to_sc[1]; } void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int screen_r[2]) { screen_r[0]= (world[0] - di->world_rect.xmin)*di->wo_to_sc[0]; screen_r[1]= (world[1] - di->world_rect.ymin)*di->wo_to_sc[1]; } void glaEnd2DDraw(gla2DDrawInfo *di) { glViewport(di->orig_vp[0], di->orig_vp[1], di->orig_vp[2], di->orig_vp[3]); glScissor(di->orig_vp[0], di->orig_vp[1], di->orig_vp[2], di->orig_vp[3]); glMatrixMode(GL_PROJECTION); glLoadMatrixf(di->orig_projmat); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(di->orig_viewmat); MEM_freeN(di); }