diff options
Diffstat (limited to 'source/blender/src/mywindow.c')
-rw-r--r-- | source/blender/src/mywindow.c | 645 |
1 files changed, 645 insertions, 0 deletions
diff --git a/source/blender/src/mywindow.c b/source/blender/src/mywindow.c new file mode 100644 index 00000000000..cf6d002ee5f --- /dev/null +++ b/source/blender/src/mywindow.c @@ -0,0 +1,645 @@ +/** + * $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 ***** + * vervanging voor een aantal fie's zoals swinopen, winset, (zie onder) + * dit alles omdat GL en X te traag zijn + * feb: Opengl en toch maar naar X! + */ + +#include <string.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_gsqueue.h" + +#include "DNA_screen_types.h" + +#include "BKE_global.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" + +#include "mydevice.h" +#include "blendef.h" + +#include "winlay.h" + + +typedef struct { + unsigned short event; + short val; + char ascii; +} QEvent; + +typedef struct { + struct bWindow *next, *prev; + int id, pad; + + int xmin, xmax, ymin, ymax; + float viewmat[4][4], winmat[4][4]; + + GSQueue *qevents; +} bWindow; + +/* globals */ +static Window *winlay_mainwindow; +static int curswin=0; +static bWindow *swinarray[MAXWIN]= {0}; +static bWindow mainwindow, renderwindow; +static int mainwin_color_depth; + +void mywindow_init_mainwin(Window *win, int orx, int ory, int sizex, int sizey) +{ + int r, g, b; + + winlay_mainwindow= win; + + swinarray[1]= &mainwindow; + curswin= 1; + + mainwindow.xmin= orx; + mainwindow.ymin= ory; + mainwindow.xmax= orx+sizex-1; + mainwindow.ymax= ory+sizey-1; + mainwindow.qevents= NULL; + + myortho2(-0.5, (float)sizex-0.5, -0.5, (float)sizey-0.5); + glLoadIdentity(); + + glGetFloatv(GL_PROJECTION_MATRIX, (float *)mainwindow.winmat); + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)mainwindow.viewmat); + + glGetIntegerv(GL_RED_BITS, &r); + glGetIntegerv(GL_GREEN_BITS, &g); + glGetIntegerv(GL_BLUE_BITS, &b); + + mainwin_color_depth= r + g + b; +} + +/* XXXXXXXXXXXXXXXX very hacky, not allowed to release + * again after 2.24 + */ +void mywindow_build_and_set_renderwin(void) +{ + glGetFloatv(GL_PROJECTION_MATRIX, (float *)renderwindow.winmat); + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)renderwindow.viewmat); + + swinarray[2]= &renderwindow; + renderwindow.qevents= NULL; + + curswin= 2; +} + +/* ------------------------------------------------------------------------- */ + + /* XXXXX, remove later */ +static bWindow *bwin_from_winid(int winid) +{ + bWindow *bwin= swinarray[winid]; + if (!bwin) { + printf("bwin_from_winid: Internal error, bad winid: %d\n", winid); + } + return bwin; +} + +int bwin_qtest(int winid) +{ + return !BLI_gsqueue_is_empty(bwin_from_winid(winid)->qevents); +} +unsigned short bwin_qread(int winid, short *val_r, char *ascii_r) +{ + if (bwin_qtest(winid)) { + QEvent evt; + BLI_gsqueue_pop(bwin_from_winid(winid)->qevents, &evt); + *val_r= evt.val; + *ascii_r= evt.ascii; + return evt.event; + } else { + *val_r= 0; + return 0; + } +} +void bwin_qadd(int winid, unsigned short event, short val, char ascii) +{ + QEvent evt; + evt.event= event; + evt.val= val; + evt.ascii= ascii; + BLI_gsqueue_push(bwin_from_winid(winid)->qevents, &evt); +} + +/* ------------------------------------------------------------------------- */ + +void bwin_get_rect(int winid, rcti *rect_r) +{ + bWindow *win= bwin_from_winid(winid); + + rect_r->xmin= win->xmin; + rect_r->ymin= win->ymin; + rect_r->xmax= win->xmax; + rect_r->ymax= win->ymax; +} + +void bwin_getsize(int win, int *x, int *y) +{ + if(win<4) { + if (win==1) { + window_get_size(winlay_mainwindow, x, y); + } else { + printf("bwin_getsize: Internal error, bad winid: %d\n", win); + *x= *y= 0; + } + } else { + bWindow *bwin= swinarray[win]; + if (bwin) { + *x= bwin->xmax-bwin->xmin+1; + *y= bwin->ymax-bwin->ymin+1; + } + } +} + +void bwin_getsuborigin(int win, int *x, int *y) +{ + if(win<4) { + *x= *y= 0; + } else { + bWindow *bwin= swinarray[win]; + if (bwin) { + *x= bwin->xmin; + *y= bwin->ymin; + } + } +} + +void bwin_getsinglematrix(int winid, float mat[][4]) +{ + bWindow *win; + float matview[4][4], matproj[4][4]; + + win= swinarray[winid]; + if(win==0) { + glGetFloatv(GL_PROJECTION_MATRIX, (float *)matproj); + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)matview); + Mat4MulMat4(mat, matview, matproj); + } + else { + Mat4MulMat4(mat, win->viewmat, win->winmat); + } +} + +/* ------------------------------------------------------------------------- */ + +void bwin_load_viewmatrix(int winid, float mat[][4]) +{ + bWindow *win= bwin_from_winid(winid); + + glLoadMatrixf(mat); + Mat4CpyMat4(win->viewmat, mat); +} +void bwin_load_winmatrix(int winid, float mat[][4]) +{ + bWindow *win= bwin_from_winid(winid); + + glLoadMatrixf(mat); + Mat4CpyMat4(win->winmat, mat); +} + +void bwin_get_viewmatrix(int winid, float mat[][4]) +{ + bWindow *win= bwin_from_winid(winid); + Mat4CpyMat4(mat, win->viewmat); +} +void bwin_get_winmatrix(int winid, float mat[][4]) +{ + bWindow *win= bwin_from_winid(winid); + Mat4CpyMat4(mat, win->winmat); +} + +void bwin_multmatrix(int winid, float mat[][4]) +{ + bWindow *win= bwin_from_winid(winid); + + glMultMatrixf((float*) mat); + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)win->viewmat); +} + +void bwin_clear_viewmat(int swin) +{ + bWindow *win; + + win= swinarray[swin]; + if(win==0) return; + + memset(win->viewmat, 0, sizeof(win->viewmat)); + win->viewmat[0][0]= 1.0; + win->viewmat[1][1]= 1.0; + win->viewmat[2][2]= 1.0; + win->viewmat[3][3]= 1.0; +} + + +void myloadmatrix(float mat[][4]) +{ + if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW) { + bwin_load_viewmatrix(curswin, mat); + } else { + bwin_load_winmatrix(curswin, mat); + } +} + +void mygetmatrix(float mat[][4]) +{ + if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW) { + bwin_get_viewmatrix(curswin, mat); + } else { + bwin_get_winmatrix(curswin, mat); + } +} + +void mymultmatrix(float mat[][4]) +{ + bwin_multmatrix(curswin, mat); +} + +void mygetsingmatrix(float mat[][4]) +{ + bwin_getsinglematrix(curswin, mat); +} + +int mywinget(void) +{ + return curswin; +} + +void mywinset(int wid) +{ + bWindow *win; + + win= swinarray[wid]; + if(win==0) { + printf("mywinset %d: doesn't exist\n", wid); + return; + } + + if (wid == 1) { /* main window */ + glViewport(0, 0, ( win->xmax-win->xmin)+1, ( win->ymax-win->ymin)+1); + glScissor(0, 0, ( win->xmax-win->xmin)+1, ( win->ymax-win->ymin)+1); + } + else { + int width= (win->xmax - win->xmin)+1; + int height= (win->ymax - win->ymin)+1; + + /* CRITICAL, this clamping ensures that + * the viewport never goes outside the screen + * edges (assuming the x, y coords aren't + * outside). This causes a hardware lock + * on Matrox cards if it happens. + * + * Really Blender should never _ever_ try + * to do such a thing, but just to be safe + * clamp it anyway (or fix the bScreen + * scaling routine, and be damn sure you + * fixed it). - zr + */ + if (win->xmin + width>G.curscreen->sizex) + width= G.curscreen->sizex - win->xmin; + if (win->ymin + height>G.curscreen->sizey) + height= G.curscreen->sizey - win->ymin; + + glViewport(win->xmin, win->ymin, width, height); + glScissor(win->xmin, win->ymin, width, height); + } + + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(&win->winmat[0][0]); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(&win->viewmat[0][0]); + + glFinish(); + + curswin= wid; +} + +int myswinopen(int parentid, int xmin, int xmax, int ymin, int ymax) +{ + bWindow *win= NULL; + int freewinid; + + for (freewinid= 4; freewinid<MAXWIN; freewinid++) + if (!swinarray[freewinid]) + break; + + if (freewinid==MAXWIN) { + printf("too many windows\n"); + + return 0; + } else { + win= MEM_callocN(sizeof(*win), "winopen"); + + win->id= freewinid; + swinarray[win->id]= win; + + win->xmin= xmin; + win->ymin= ymin; + win->xmax= xmax; + win->ymax= ymax; + + win->qevents= BLI_gsqueue_new(sizeof(QEvent)); + + Mat4One(win->viewmat); + Mat4One(win->winmat); + + mywinset(win->id); + + return win->id; + } +} + +void mywinclose(int winid) +{ + if (winid<4) { + if (winid==1) { + window_destroy(winlay_mainwindow); + winlay_mainwindow= NULL; + } else { + printf("mwinclose: Internal error, bad winid: %d\n", winid); + } + } else { + bWindow *win= swinarray[winid]; + + if (win) { + BLI_gsqueue_free(win->qevents); + MEM_freeN(win); + } else { + printf("mwinclose: Internal error, bad winid: %d\n", winid); + } + } + + swinarray[winid]= 0; + if (curswin==winid) curswin= 0; +} + +void mywinposition(int winid, int xmin, int xmax, int ymin, int ymax) /* let op: andere syntax */ +{ + bWindow *win= bwin_from_winid(winid); + + win->xmin= xmin; + win->ymin= ymin; + win->xmax= xmax; + win->ymax= ymax; +} + + +void bwin_ortho(int winid, float x1, float x2, float y1, float y2, float n, float f) +{ + bWindow *bwin= bwin_from_winid(winid); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(x1, x2, y1, y2, n, f); + + glGetFloatv(GL_PROJECTION_MATRIX, (float *)bwin->winmat); + glMatrixMode(GL_MODELVIEW); +} + +void bwin_ortho2(int win, float x1, float x2, float y1, float y2) +{ + bwin_ortho(win, x1, x2, y1, y2, -1, 1); +} + +void bwin_frustum(int winid, float x1, float x2, float y1, float y2, float n, float f) +{ + bWindow *win= bwin_from_winid(winid); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(x1, x2, y1, y2, n, f); + + glGetFloatv(GL_PROJECTION_MATRIX, (float *)win->winmat); + glMatrixMode(GL_MODELVIEW); +} + +void myortho(float x1, float x2, float y1, float y2, float n, float f) +{ + bwin_ortho(curswin, x1, x2, y1, y2, n, f); +} + +void myortho2(float x1, float x2, float y1, float y2) +{ + bwin_ortho(curswin, x1, x2, y1, y2, -1, 1); +} + +void mywindow(float x1, float x2, float y1, float y2, float n, float f) +{ + bwin_frustum(curswin, x1, x2, y1, y2, n, f); +} + +unsigned int index_to_framebuffer(int index) +{ + unsigned int i= index; + + switch(mainwin_color_depth) { + case 8: + i= ((i & 48)<<18) + ((i & 12)<<12) + ((i & 3)<<6); + i |= 0x3F3F3F; + break; + case 12: + i= ((i & 0xF00)<<12) + ((i & 0xF0)<<8) + ((i & 0xF)<<4); + /* sometimes dithering subtracts! */ + i |= 0x0F0F0F; + break; + case 15: + case 16: + i= ((i & 0x7C00)<<9) + ((i & 0x3E0)<<6) + ((i & 0x1F)<<3); + i |= 0x070707; + break; + default: + i= ((i & 0x3F000)<<6) + ((i & 0xFC0)<<4) + ((i & 0x3F)<<2); + i |= 0x030303; + break; + } + + return i; +} + +int framebuffer_to_index(unsigned int col) +{ + if (col==0) return 0; + + switch(mainwin_color_depth) { + case 8: + return ((col & 0xC00000)>>18) + ((col & 0xC000)>>12) + ((col & 0xC0)>>6); + case 12: + return ((col & 0xF00000)>>12) + ((col & 0xF000)>>8) + ((col & 0xF0)>>4); + case 15: + case 16: + return ((col & 0xF80000)>>9) + ((col & 0xF800)>>6) + ((col & 0xF8)>>3); + default: + return ((col & 0xFC0000)>>6) + ((col & 0xFC00)>>4) + ((col & 0xFC)>>2); + } +} + + +/* ********** END MY WINDOW ************** */ + +#ifdef WIN32 +static int is_a_really_crappy_nvidia_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), "NVIDIA Corporation") == 0); + + return well_is_it; +} +#endif + +void myswapbuffers(void) +{ + ScrArea *sa; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->win_swap==WIN_BACK_OK) sa->win_swap= WIN_FRONT_OK; + if(sa->head_swap==WIN_BACK_OK) sa->head_swap= WIN_FRONT_OK; + + sa= sa->next; + } + + /* HACK, some windows drivers feel they should honor the scissor + * test when swapping buffers, disable the test while swapping + * on WIN32. (namely Matrox and NVidia's new drivers around Oct 1 2001) + * - zr + */ + +#ifdef WIN32 + /* HACK, in some NVidia driver release some kind of + * fancy optimiziation (I presume) was put in which for + * some reason causes parts of the buffer not to be + * swapped. One way to defeat it is the following wierd + * code (which we only do for nvidia cards). This should + * be removed if NVidia fixes their drivers. - zr + */ + if (is_a_really_crappy_nvidia_card()) { + glDrawBuffer(GL_FRONT); + + glBegin(GL_LINES); + glEnd(); + + glDrawBuffer(GL_BACK); + } + + glDisable(GL_SCISSOR_TEST); + window_swap_buffers(winlay_mainwindow); + glEnable(GL_SCISSOR_TEST); +#else + window_swap_buffers(winlay_mainwindow); +#endif +} + + +/* *********************** PATTERNS ENZO ***************** */ + +void setlinestyle(int nr) +{ + if(nr==0) { + glDisable(GL_LINE_STIPPLE); + } + else { + + glEnable(GL_LINE_STIPPLE); + glLineStipple(nr, 0xAAAA); + } +} + +/*******************/ +/*******************/ +/* Menu utilities */ + +static int *frontbuffer_save= NULL; +static int ov_x, ov_y, ov_sx, ov_sy; + +void my_put_frontbuffer_image(void) +{ + if (frontbuffer_save) { + glRasterPos2f( (float)ov_x -0.5, (float)ov_y - 0.5 ); + glDrawPixels(ov_sx, ov_sy, GL_RGBA, GL_UNSIGNED_BYTE, frontbuffer_save); + MEM_freeN(frontbuffer_save); + frontbuffer_save= NULL; + } +} + +void my_get_frontbuffer_image(int x, int y, int sx, int sy) +{ + if(frontbuffer_save) return; + + ov_x= x; + ov_y= y; + ov_sx= sx; + ov_sy= sy; + + if(sx>1 && sy>1) { + frontbuffer_save= MEM_mallocN(sx*sy*4, "temp_frontbuffer_image"); + glReadPixels(x, y, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, frontbuffer_save); + } + + #ifdef WIN32 + /* ander coordinatensysteem! */ + y= (G.curscreen->sizey-y); + + if(curswin>3) { + y -= curarea->winrct.ymin; + } + #endif +} + +int mywin_inmenu(void) { + return frontbuffer_save?1:0; +} + +void mywin_getmenu_rect(int *x, int *y, int *sx, int *sy) { + *x= ov_x; + *sx= ov_sx; + *sy= ov_sy; + +#if defined(WIN32) || defined (__BeOS) + *y= ov_y; +#else + *y= (G.curscreen->sizey - ov_y) - ov_sy; +#endif +} |