diff options
Diffstat (limited to 'source/blender/src/glutil.c')
-rw-r--r-- | source/blender/src/glutil.c | 695 |
1 files changed, 0 insertions, 695 deletions
diff --git a/source/blender/src/glutil.c b/source/blender/src/glutil.c deleted file mode 100644 index 13922bb7eef..00000000000 --- a/source/blender/src/glutil.c +++ /dev/null @@ -1,695 +0,0 @@ - - -/** - * $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 <stdio.h> -#include <math.h> -#include <string.h> - -#include "MEM_guardedalloc.h" - -#include "DNA_vec_types.h" -#include "DNA_listBase.h" - -#include "BKE_utildefines.h" - -#include "BLI_arithb.h" -#include "BLI_threads.h" - -#include "BIF_gl.h" -#include "BIF_glutil.h" -#include "BIF_mywindow.h" - -#ifndef GL_CLAMP_TO_EDGE -#define GL_CLAMP_TO_EDGE 0x812F -#endif - - - /* Invert line handling */ - -#define glToggle(mode, onoff) (((onoff)?glEnable:glDisable)(mode)) - -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) -{ - glReadBuffer(GL_FRONT); - glDrawBuffer(GL_FRONT); - sdrawXORline(x0, y0, x1, y1); - glFlush(); - glReadBuffer(GL_BACK); - 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}; - - /* with builtin memory, max 4 lines */ - - 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 fdrawXORellipse(float xofs, float yofs, float hw, float hh) -{ - if(hw==0) return; - - set_inverted_drawing(1); - - glPushMatrix(); - glTranslatef(xofs, yofs, 0.0); - glScalef(1,hh/hw,1); - glutil_draw_lined_arc(0.0, M_PI*2.0, hw, 20); - glPopMatrix(); - - set_inverted_drawing(0); -} -void fdrawXORcirc(float xofs, float yofs, float rad) -{ - set_inverted_drawing(1); - - glPushMatrix(); - glTranslatef(xofs, yofs, 0.0); - glutil_draw_lined_arc(0.0, M_PI*2.0, 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<nsegments; i++) { - float t= (float) i/(nsegments-1); - float cur= start + t*angle; - - glVertex2f(cos(cur)*radius, sin(cur)*radius); - } - glEnd(); -} - -void glutil_draw_lined_arc(float start, float angle, float radius, int nsegments) { - int i; - - glBegin(GL_LINE_STRIP); - for (i=0; i<nsegments; i++) { - float t= (float) i/(nsegments-1); - float cur= start + t*angle; - - glVertex2f(cos(cur)*radius, sin(cur)*radius); - } - glEnd(); -} - -int glaGetOneInteger(int param) -{ - GLint i; - glGetIntegerv(param, &i); - return i; -} - -float glaGetOneFloat(int param) -{ - GLfloat v; - glGetFloatv(param, &v); - return v; -} - -void glaRasterPosSafe2f(float x, float y, float known_good_x, float known_good_y) -{ - GLubyte dummy= 0; - - /* As long as known good coordinates are correct - * this is guarenteed to generate an ok raster - * position (ignoring potential (real) overflow - * issues). - */ - glRasterPos2f(known_good_x, known_good_y); - - /* Now shift the raster position to where we wanted - * it in the first place using the glBitmap trick. - */ - glBitmap(0, 0, 0, 0, x - known_good_x, y - known_good_y, &dummy); -} - -static int get_cached_work_texture(int *w_r, int *h_r) -{ - static GLint texid= -1; - static int tex_w= 256; - static int tex_h= 256; - - if (texid==-1) { - GLint ltexid= glaGetOneInteger(GL_TEXTURE_2D); - unsigned char *tbuf; - - glGenTextures(1, (GLuint *)&texid); - - glBindTexture(GL_TEXTURE_2D, texid); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - tbuf= MEM_callocN(tex_w*tex_h*4, "tbuf"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tbuf); - MEM_freeN(tbuf); - - glBindTexture(GL_TEXTURE_2D, ltexid); - } - - *w_r= tex_w; - *h_r= tex_h; - return texid; -} - -void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *rect) -{ - unsigned char *uc_rect= (unsigned char*) rect; - float *f_rect= (float *)rect; - float xzoom= glaGetOneFloat(GL_ZOOM_X), yzoom= glaGetOneFloat(GL_ZOOM_Y); - int ltexid= glaGetOneInteger(GL_TEXTURE_2D); - int lrowlength= glaGetOneInteger(GL_UNPACK_ROW_LENGTH); - int subpart_x, subpart_y, tex_w, tex_h; - int texid= get_cached_work_texture(&tex_w, &tex_h); - int nsubparts_x= (img_w+(tex_w-1))/tex_w; - int nsubparts_y= (img_h+(tex_h-1))/tex_h; - - /* Specify the color outside this function, and tex will modulate it. - * This is useful for changing alpha without using glPixelTransferf() - */ - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w); - glBindTexture(GL_TEXTURE_2D, texid); - - /* don't want nasty border artifacts */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - for (subpart_y=0; subpart_y<nsubparts_y; subpart_y++) { - for (subpart_x=0; subpart_x<nsubparts_x; subpart_x++) { - int subpart_w= (subpart_x==nsubparts_x-1)?(img_w-subpart_x*tex_w):tex_w; - int subpart_h= (subpart_y==nsubparts_y-1)?(img_h-subpart_y*tex_h):tex_h; - float rast_x= x+subpart_x*tex_w*xzoom; - float rast_y= y+subpart_y*tex_h*yzoom; - - if(format==GL_FLOAT) - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, GL_RGBA, GL_FLOAT, &f_rect[(subpart_y*tex_w)*img_w*4 + (subpart_x*tex_w)*4]); - else - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, GL_RGBA, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y*tex_w)*img_w*4 + (subpart_x*tex_w)*4]); - - glEnable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(rast_x, rast_y); - - glTexCoord2f((float) (subpart_w-1)/tex_w, 0); - glVertex2f(rast_x+subpart_w*xzoom, rast_y); - - glTexCoord2f((float) (subpart_w-1)/tex_w, (float) subpart_h/tex_h); - glVertex2f(rast_x+subpart_w*xzoom, rast_y+subpart_h*yzoom); - - glTexCoord2f(0, (float) subpart_h/tex_h); - glVertex2f(rast_x, rast_y+subpart_h*yzoom); - glEnd(); - glDisable(GL_TEXTURE_2D); - } - } - - glBindTexture(GL_TEXTURE_2D, ltexid); - glPixelStorei(GL_UNPACK_ROW_LENGTH, lrowlength); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -} - -#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val)) -void glaDrawPixelsSafe_to32(float fx, float fy, int img_w, int img_h, int row_w, float *rectf) -{ - float *rf; - int x, y; - char *rect32, *rc; - - /* copy imgw-imgh to a temporal 32 bits rect */ - if(img_w<1 || img_h<1) return; - - rc= rect32= MEM_mallocN(img_w*img_h*sizeof(int), "temp 32 bits"); - - for(y=0; y<img_h; y++) { - rf= rectf; - for(x=0; x<img_w; x++, rf+=4, rc+=4) { - rc[0]= FTOCHAR(rf[0]); - rc[1]= FTOCHAR(rf[1]); - rc[2]= FTOCHAR(rf[2]); - rc[3]= FTOCHAR(rf[3]); - } - rectf+= 4*row_w; - } - - glaDrawPixelsSafe(fx, fy, img_w, img_h, img_w, GL_RGBA, GL_UNSIGNED_BYTE, rect32); - - MEM_freeN(rect32); -} - -void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect) -{ - 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= -x/xzoom; - float iy= -y/yzoom; - - /* The maximum pixel amounts the image can be cropped - * at the lower left without exceeding the origin. - */ - int off_x= floor(MAX2(ix, 0)); - int off_y= floor(MAX2(iy, 0)); - - /* The zoomed space coordinate of the raster position - * (starting at the lower left most unclipped pixel). - */ - float rast_x= x + off_x*xzoom; - float rast_y= y + off_y*yzoom; - - GLfloat scissor[4]; - int draw_w, draw_h; - - /* Determine the smallest number of pixels we need to draw - * before the image would go off the upper right corner. - * - * It may seem this is just an optimization but some graphics - * cards (ATI) freak out if there is a large zoom factor and - * a large number of pixels off the screen (probably at some - * level the number of image pixels to draw is getting multiplied - * by the zoom and then clamped). Making sure we draw the - * fewest pixels possible keeps everyone mostly happy (still - * fails if we zoom in on one really huge pixel so that it - * covers the entire screen). - */ - glGetFloatv(GL_SCISSOR_BOX, scissor); - draw_w = MIN2(img_w-off_x, ceil((scissor[2]-rast_x)/xzoom)); - draw_h = MIN2(img_h-off_y, ceil((scissor[3]-rast_y)/yzoom)); - - if (draw_w>0 && draw_h>0) { - int old_row_length = glaGetOneInteger(GL_UNPACK_ROW_LENGTH); - - /* Don't use safe RasterPos (slower) if we can avoid it. */ - if (rast_x>=0 && rast_y>=0) { - glRasterPos2f(rast_x, rast_y); - } else { - glaRasterPosSafe2f(rast_x, rast_y, 0, 0); - } - - glPixelStorei(GL_UNPACK_ROW_LENGTH, row_w); - if(format==GL_LUMINANCE || format==GL_RED) { - if(type==GL_FLOAT) { - float *f_rect= (float *)rect; - glDrawPixels(draw_w, draw_h, format, type, f_rect + (off_y*row_w + off_x)); - } - else if(type==GL_INT || type==GL_UNSIGNED_INT) { - int *i_rect= (int *)rect; - glDrawPixels(draw_w, draw_h, format, type, i_rect + (off_y*row_w + off_x)); - } - } - else { /* RGBA */ - if(type==GL_FLOAT) { - float *f_rect= (float *)rect; - glDrawPixels(draw_w, draw_h, format, type, f_rect + (off_y*row_w + off_x)*4); - } - else if(type==GL_UNSIGNED_BYTE) { - unsigned char *uc_rect= (unsigned char *) rect; - glDrawPixels(draw_w, draw_h, format, type, uc_rect + (off_y*row_w + off_x)*4); - } - } - - glPixelStorei(GL_UNPACK_ROW_LENGTH, old_row_length); - } -} - -/* 2D Drawing Assistance */ - -void glaDefine2DArea(rcti *screen_rect) -{ - int sc_w= screen_rect->xmax - 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]; -}; - -void gla2DGetMap(gla2DDrawInfo *di, rctf *rect) -{ - *rect= di->world_rect; -} - -void gla2DSetMap(gla2DDrawInfo *di, rctf *rect) -{ - int sc_w, sc_h; - float wo_w, wo_h; - - di->world_rect= *rect; - - 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; -} - - -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, (GLint *)di->orig_vp); - glGetIntegerv(GL_SCISSOR_BOX, (GLint *)di->orig_sc); - glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *)di->orig_projmat); - glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)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); -} - -/* **************** glPoint hack ************************ */ - -static int curmode=0; -static int pointhack=0; -static GLubyte Squaredot[16] = { 0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff}; - -void bglBegin(int mode) -{ - curmode= mode; - - if(mode==GL_POINTS) { - float value[4]; - glGetFloatv(GL_POINT_SIZE_RANGE, value); - if(value[1]<2.0) { - glGetFloatv(GL_POINT_SIZE, value); - pointhack= floor(value[0]+0.5); - if(pointhack>4) pointhack= 4; - } - else glBegin(mode); - } -} - - -void bglVertex3fv(float *vec) -{ - switch(curmode) { - case GL_POINTS: - if(pointhack) { - glRasterPos3fv(vec); - glBitmap(pointhack, pointhack, (float)pointhack/2.0, (float)pointhack/2.0, 0.0, 0.0, Squaredot); - } - else glVertex3fv(vec); - break; - } -} - -void bglVertex3f(float x, float y, float z) -{ - switch(curmode) { - case GL_POINTS: - if(pointhack) { - glRasterPos3f(x, y, z); - glBitmap(pointhack, pointhack, (float)pointhack/2.0, (float)pointhack/2.0, 0.0, 0.0, Squaredot); - } - else glVertex3f(x, y, z); - break; - } -} - -void bglVertex2fv(float *vec) -{ - switch(curmode) { - case GL_POINTS: - if(pointhack) { - glRasterPos2fv(vec); - glBitmap(pointhack, pointhack, (float)pointhack/2, pointhack/2, 0.0, 0.0, Squaredot); - } - else glVertex2fv(vec); - break; - } -} - - -void bglEnd(void) -{ - if(pointhack) pointhack= 0; - else glEnd(); - -} - -/* Uses current OpenGL state to get view matrices for gluProject/gluUnProject */ -void bgl_get_mats(bglMats *mats) -{ - const double badvalue= 1.0e-6; - - glGetDoublev(GL_MODELVIEW_MATRIX, mats->modelview); - glGetDoublev(GL_PROJECTION_MATRIX, mats->projection); - glGetIntegerv(GL_VIEWPORT, (GLint *)mats->viewport); - - /* Very strange code here - it seems that certain bad values in the - modelview matrix can cause gluUnProject to give bad results. */ - if(mats->modelview[0] < badvalue && - mats->modelview[0] > -badvalue) - mats->modelview[0]= 0; - if(mats->modelview[5] < badvalue && - mats->modelview[5] > -badvalue) - mats->modelview[5]= 0; - - /* Set up viewport so that gluUnProject will give correct values */ - mats->viewport[0] = 0; - mats->viewport[1] = 0; -} - -/* *************** glPolygonOffset hack ************* */ - -// both temporal, so here for now (ton) -#include "BKE_global.h" -#include "DNA_view3d_types.h" - -/* dist is only for ortho now... */ -void bglPolygonOffset(float dist) -{ - static float winmat[16], offset=0.0; - - if(dist!=0.0) { - float offs; - - // glEnable(GL_POLYGON_OFFSET_FILL); - // glPolygonOffset(-1.0, -1.0); - - /* hack below is to mimic polygon offset */ - glMatrixMode(GL_PROJECTION); - glGetFloatv(GL_PROJECTION_MATRIX, (float *)winmat); - - /* dist is from camera to center point */ - - if(winmat[15]>0.5) offs= 0.00001*dist*G.vd->dist; // ortho tweaking - else offs= 0.0005*dist; // should be clipping value or so... - - winmat[14]-= offs; - offset+= offs; - - glLoadMatrixf(winmat); - glMatrixMode(GL_MODELVIEW); - } - else { - - glMatrixMode(GL_PROJECTION); - winmat[14]+= offset; - offset= 0.0; - glLoadMatrixf(winmat); - glMatrixMode(GL_MODELVIEW); - } -} - -int is_a_really_crappy_intel_card(void) -{ - static int well_is_it= -1; - - /* Do you understand the implication? Do you? */ - if (well_is_it==-1) - well_is_it= (strcmp((char*) glGetString(GL_VENDOR), "Intel Inc.") == 0); - - return well_is_it; -} - -void bglFlush(void) -{ - glFlush(); -#ifdef __APPLE__ - if(is_a_really_crappy_intel_card()) - myswapbuffers(); //hack to get mac intel graphics to show frontbuffer -#endif -} - - |